@adatechnology/game-shapes 0.0.0-stage → 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/LICENSE +21 -0
- package/README.md +152 -2
- package/dist/chunk-IFXQIDSA.js +2984 -0
- package/dist/chunk-IFXQIDSA.js.map +1 -0
- package/dist/index.d.ts +253 -0
- package/dist/index.global.js +3270 -0
- package/dist/index.global.js.map +1 -0
- package/dist/index.js +276 -0
- package/dist/index.js.map +1 -0
- package/dist/worker-BZ7plgyI.d.ts +394 -0
- package/dist/worker.d.ts +1 -0
- package/dist/worker.js +7 -0
- package/dist/worker.js.map +1 -0
- package/package.json +59 -3
- package/schema/shape.schema.json +703 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
import { S as ShapeSchema, G as GenerateOptions, a as ShapeBuffers, b as ShapeNode, P as PrimitiveNode, c as PrimitiveBuffers, d as ShapeOutline, B as BevelSpec, V as Vec3, H as HoleSpec, e as ShapeGenerator, C as Color, T as Transform, R as RotationOrder } from './worker-BZ7plgyI.js';
|
|
2
|
+
export { f as Bounds, g as BoxNode, h as CircleNode, i as ConeNode, j as CustomNode, k as CylinderNode, D as DifferenceNode, E as ExtrudeNode, l as GeneratorContext, m as GeometryGroup, n as GroupNode, I as InstanceSpec, o as InstancedBatch, L as LatheNode, p as LodLevel, M as Mat4, q as MaterialHint, r as MeshNode, N as NamedRange, s as NodeCommon, t as PlaneNode, u as PointNode, v as RingNode, w as ShapeBatch, x as ShapeJob, y as ShapeKind, z as ShapeLevel, A as ShapePart, F as ShapePoint, J as ShapeReply, K as ShapeStats, O as ShapeWorkerOptions, Q as SphereNode, U as TorusNode, W as UvRect, X as Vec2, Y as WorkerScopeLike, Z as installShapeWorker } from './worker-BZ7plgyI.js';
|
|
3
|
+
|
|
4
|
+
declare const isPrimitiveNode: (node: ShapeNode) => node is PrimitiveNode;
|
|
5
|
+
/** The options that change the output, as they enter the cache key. */
|
|
6
|
+
declare function keyOptions(options?: GenerateOptions): Record<string, unknown>;
|
|
7
|
+
/** The cache key of a shape under some options: 64-bit FNV-1a of the canonical schema text and the options that change the output. */
|
|
8
|
+
declare const shapeKey: (schema: ShapeSchema, options?: GenerateOptions) => string;
|
|
9
|
+
/**
|
|
10
|
+
* Turns a shape into buffers: one batch per (part, material) per level, baked; instanced nodes as instance batches; parts with their pivots;
|
|
11
|
+
* points. Pure: the same schema and options give the same bytes, here or in a worker.
|
|
12
|
+
*/
|
|
13
|
+
declare function generate(schema: ShapeSchema, options?: GenerateOptions): ShapeBuffers;
|
|
14
|
+
|
|
15
|
+
declare function box(width?: number, height?: number, depth?: number, widthSegments?: number, heightSegments?: number, depthSegments?: number): PrimitiveBuffers;
|
|
16
|
+
declare function cylinder(radiusTop?: number, radiusBottom?: number, height?: number, radialSegments?: number, heightSegments?: number, openEnded?: boolean, thetaStart?: number, thetaLength?: number): PrimitiveBuffers;
|
|
17
|
+
declare function cone(radius?: number, height?: number, radialSegments?: number, heightSegments?: number, openEnded?: boolean, thetaStart?: number, thetaLength?: number): PrimitiveBuffers;
|
|
18
|
+
declare function sphere(radius?: number, widthSegments?: number, heightSegments?: number, phiStart?: number, phiLength?: number, thetaStart?: number, thetaLength?: number): PrimitiveBuffers;
|
|
19
|
+
declare function plane(width?: number, height?: number, widthSegments?: number, heightSegments?: number): PrimitiveBuffers;
|
|
20
|
+
declare function circle(radius?: number, segments?: number, thetaStart?: number, thetaLength?: number): PrimitiveBuffers;
|
|
21
|
+
declare function ring(innerRadius?: number, outerRadius?: number, thetaSegments?: number, phiSegments?: number, thetaStart?: number, thetaLength?: number): PrimitiveBuffers;
|
|
22
|
+
declare function lathe(points: ReadonlyArray<readonly [number, number]>, segments?: number, phiStart?: number, phiLength?: number): PrimitiveBuffers;
|
|
23
|
+
declare function torus(radius?: number, tube?: number, radialSegments?: number, tubularSegments?: number, arc?: number): PrimitiveBuffers;
|
|
24
|
+
|
|
25
|
+
/** `BufferGeometry.computeVertexNormals` for non-indexed Float32 positions, then `normalizeNormals`, both stored as Float32. */
|
|
26
|
+
declare function computeVertexNormals(positions: Float32Array, indices?: ArrayLike<number>): Float32Array;
|
|
27
|
+
declare function extrude(outline: ShapeOutline, depth?: number, steps?: number, bevel?: false | BevelSpec | undefined): PrimitiveBuffers;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* A box (centred, `size = [w, h, d]`) minus rectangular prisms that go all the way through it along z: the cheap, exact boolean (walls with
|
|
31
|
+
* windows and doors). The face is cut into a grid at every hole edge; each solid cell gets its front and back quads, and every cell edge between
|
|
32
|
+
* solid and empty (a hole or the outside) gets a quad over the depth facing the empty side, so the outer sides and the reveals come out of the
|
|
33
|
+
* same rule. Front uvs map the face to [0, 1]; side uvs run along the edge and the depth.
|
|
34
|
+
*/
|
|
35
|
+
declare function difference(size: Vec3, subtract: readonly HoleSpec[]): PrimitiveBuffers;
|
|
36
|
+
|
|
37
|
+
/** How a level of detail changes a primitive. */
|
|
38
|
+
interface DetailOptions {
|
|
39
|
+
/** Multiplies the segment counts of round primitives (1 leaves them as given). */
|
|
40
|
+
readonly detail?: number;
|
|
41
|
+
/** Floor of the scaled segment counts (default 3). */
|
|
42
|
+
readonly minSegments?: number;
|
|
43
|
+
}
|
|
44
|
+
/** The parameters of a primitive node (no transform, colour or name), with the level of detail applied: what its geometry depends on. */
|
|
45
|
+
declare function primitiveParameters(node: PrimitiveNode, options?: DetailOptions): Record<string, unknown>;
|
|
46
|
+
/** Sets how many primitive templates are kept (least recently used out; 0 turns the cache off). */
|
|
47
|
+
declare function setTemplateCacheSize(size: number): void;
|
|
48
|
+
declare function clearTemplateCache(): void;
|
|
49
|
+
declare const templateCacheStats: () => {
|
|
50
|
+
size: number;
|
|
51
|
+
hits: number;
|
|
52
|
+
misses: number;
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* The geometry of one primitive on its own, not baked: the arrays three's generator of the same kind builds, bit for bit (meshes and differences
|
|
56
|
+
* are `BufferGeometry`). The result comes from a shared template cache and must not be written to (copy it with `clonePrimitive`).
|
|
57
|
+
*/
|
|
58
|
+
declare function buildPrimitive(node: PrimitiveNode, options?: DetailOptions): PrimitiveBuffers;
|
|
59
|
+
/** A copy that owns its arrays. */
|
|
60
|
+
declare function clonePrimitive(p: PrimitiveBuffers): PrimitiveBuffers;
|
|
61
|
+
|
|
62
|
+
/** One piece for `mergeTransformed`: arrays (any may be missing) and the matrix that takes them into the merged space. */
|
|
63
|
+
interface TransformedPiece {
|
|
64
|
+
readonly positions: ArrayLike<number>;
|
|
65
|
+
readonly normals?: ArrayLike<number>;
|
|
66
|
+
readonly uvs?: ArrayLike<number>;
|
|
67
|
+
readonly indices?: ArrayLike<number> | null;
|
|
68
|
+
/** Column-major 4 x 4. */
|
|
69
|
+
readonly matrix: readonly number[];
|
|
70
|
+
}
|
|
71
|
+
interface MergedArrays {
|
|
72
|
+
readonly positions: Float32Array;
|
|
73
|
+
readonly normals: Float32Array;
|
|
74
|
+
readonly uvs: Float32Array;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Joins pieces into one non-indexed set of arrays, each piece de-indexed, its missing normals and uvs zero-filled, its positions by
|
|
78
|
+
* `Vector3.applyMatrix4` and its normals by the normal matrix and normalised: what three's `toNonIndexed` + `applyMatrix4` + a join do,
|
|
79
|
+
* bit for bit (the port of `mergeByMaterial`).
|
|
80
|
+
*/
|
|
81
|
+
declare function mergeTransformed(pieces: readonly TransformedPiece[]): MergedArrays;
|
|
82
|
+
/** Every `ArrayBuffer` of a result, for `postMessage(buffers, transferablesOf(buffers))`. */
|
|
83
|
+
declare function transferablesOf(buffers: ShapeBuffers): ArrayBuffer[];
|
|
84
|
+
/** A deep copy whose arrays are its own (cached results are shared and read-only; copy before deforming). */
|
|
85
|
+
declare function cloneBuffers(buffers: ShapeBuffers): ShapeBuffers;
|
|
86
|
+
/** Bytes held by the arrays of a result (what the cache counts). */
|
|
87
|
+
declare function byteSizeOf(buffers: ShapeBuffers): number;
|
|
88
|
+
|
|
89
|
+
/** The JSON Schema (draft 2020-12) of a shape document; the same file ships as `@adatechnology/game-shapes/schema.json`. */
|
|
90
|
+
declare const SHAPE_SCHEMA: Readonly<Record<string, unknown>>;
|
|
91
|
+
/** Every rule of the JSON Schema, checked without a schema engine: one message per problem, with its path (`root.children[3].radialSegments: ...`). */
|
|
92
|
+
declare function validateShape(schema: unknown): string[];
|
|
93
|
+
/** Throws with every problem when the schema is not valid. */
|
|
94
|
+
declare function assertValidShape(schema: unknown): asserts schema is ShapeSchema;
|
|
95
|
+
|
|
96
|
+
/** The generators of one set: what `{ kind: 'custom', generator: name, params }` nodes look up. */
|
|
97
|
+
interface ShapeGenerators {
|
|
98
|
+
/**
|
|
99
|
+
* Registers a generator: a pure function of its params and a seeded stream that returns a node. A worker that generates shapes with custom nodes must
|
|
100
|
+
* register the same generators (import the same module in the worker script).
|
|
101
|
+
*/
|
|
102
|
+
register(name: string, generator: ShapeGenerator): void;
|
|
103
|
+
unregister(name: string): boolean;
|
|
104
|
+
get(name: string): ShapeGenerator | undefined;
|
|
105
|
+
list(): string[];
|
|
106
|
+
/** The generators by name, as `GenerateOptions.generators` takes them. */
|
|
107
|
+
record(): Readonly<Record<string, ShapeGenerator>>;
|
|
108
|
+
}
|
|
109
|
+
/** The set behind `registerGenerator`, `getGenerator` and the rest of the global functions, created on first use. */
|
|
110
|
+
declare const defaultShapeGenerators: () => ShapeGenerators;
|
|
111
|
+
/** @deprecated use `createShapes(...).register`. */
|
|
112
|
+
declare const registerGenerator: (name: string, generator: ShapeGenerator) => void;
|
|
113
|
+
/** @deprecated use `createShapes(...).unregister`. */
|
|
114
|
+
declare const unregisterGenerator: (name: string) => boolean;
|
|
115
|
+
/** @deprecated use `createShapes(...).get`. */
|
|
116
|
+
declare const getGenerator: (name: string) => ShapeGenerator | undefined;
|
|
117
|
+
/** @deprecated use `createShapes(...).list`. */
|
|
118
|
+
declare const listGenerators: () => string[];
|
|
119
|
+
|
|
120
|
+
interface ShapesOptions {
|
|
121
|
+
/** Generators by name, added to the set; later packs replace earlier ones with the same name. */
|
|
122
|
+
readonly packs?: readonly Readonly<Record<string, ShapeGenerator>>[];
|
|
123
|
+
/** A generator replaced by name (a function is replaced as a whole). */
|
|
124
|
+
readonly patch?: Readonly<Record<string, ShapeGenerator>>;
|
|
125
|
+
/** Names taken out. */
|
|
126
|
+
readonly remove?: readonly string[];
|
|
127
|
+
}
|
|
128
|
+
interface Shapes extends ShapeGenerators {
|
|
129
|
+
/** `generate` that looks custom nodes up in this set only (a name only the global registry has throws). */
|
|
130
|
+
generate(schema: ShapeSchema, options?: Omit<GenerateOptions, 'isolatedGenerators'>): ShapeBuffers;
|
|
131
|
+
}
|
|
132
|
+
/** A set of shape generators of its own. Nothing is shared with any other set or with the global registry. */
|
|
133
|
+
declare function createShapes(options?: ShapesOptions): Shapes;
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Canonical JSON (keys sorted, `undefined` left out, `-0` kept as `-0`, typed arrays as plain lists) and a 64-bit FNV-1a of it in two 32-bit
|
|
137
|
+
* lanes: the key a shape is cached and shared by.
|
|
138
|
+
*/
|
|
139
|
+
declare function canonicalJson(value: unknown): string;
|
|
140
|
+
/** 64-bit FNV-1a of a text as 16 hex digits (two independent 32-bit lanes). */
|
|
141
|
+
declare const hash64: (text: string) => string;
|
|
142
|
+
/** `hash64(canonicalJson(value))`. */
|
|
143
|
+
declare const hashValue: (value: unknown) => string;
|
|
144
|
+
|
|
145
|
+
/** mulberry32: a small, fast 32-bit seeded stream in [0, 1). */
|
|
146
|
+
declare function mulberry32(seed: number): () => number;
|
|
147
|
+
/** The stream of one node: its own per (seed, generator, path), so adding a node never shifts another node's draws. */
|
|
148
|
+
declare const streamFor: (seed: number | string, generator: string, path: string) => (() => number);
|
|
149
|
+
|
|
150
|
+
/** A colour as `0xRRGGBB`: numbers as given (floored, as three's `setHex`), `'#rrggbb'` strings parsed. */
|
|
151
|
+
declare function colorHex(color: Color | undefined, fallback?: number): number;
|
|
152
|
+
/** three's `SRGBToLinear` (r160 `ColorManagement`), the same constants. */
|
|
153
|
+
declare const srgbToLinear: (c: number) => number;
|
|
154
|
+
/**
|
|
155
|
+
* The rgb floats of a hex colour as three's `Color.setHex` stores them: the channels over 255 (`'srgb'`), converted to the linear working space
|
|
156
|
+
* when colour management is on (`'linear'`).
|
|
157
|
+
*/
|
|
158
|
+
declare function colorChannels(hex: number, space: 'linear' | 'srgb'): [number, number, number];
|
|
159
|
+
|
|
160
|
+
type Matrix4 = number[];
|
|
161
|
+
type Matrix3 = number[];
|
|
162
|
+
declare const identity4: () => Matrix4;
|
|
163
|
+
/** `Quaternion.setFromEuler` (x, y, z, w). */
|
|
164
|
+
declare function quaternionFromEuler(x: number, y: number, z: number, order?: RotationOrder): [number, number, number, number];
|
|
165
|
+
/** `Matrix4.compose(position, quaternion, scale)`. */
|
|
166
|
+
declare function compose(px: number, py: number, pz: number, q: readonly [number, number, number, number], sx: number, sy: number, sz: number): Matrix4;
|
|
167
|
+
/** `Matrix4.makeRotationY(theta)` followed by `setPosition(x, y, z)`. */
|
|
168
|
+
declare function headingMatrix(theta: number, x?: number, y?: number, z?: number): Matrix4;
|
|
169
|
+
/** `Matrix4.multiplyMatrices(a, b)`: a x b. */
|
|
170
|
+
declare function multiply(ae: readonly number[], be: readonly number[]): Matrix4;
|
|
171
|
+
/** `Matrix3.getNormalMatrix(m)`: the inverse transpose of the upper 3 x 3 (all zeros when singular, as three). */
|
|
172
|
+
declare function normalMatrix(me: readonly number[]): Matrix3;
|
|
173
|
+
/** True when the last row is (0, 0, 0, 1): `applyMatrix4`'s divide by w is then a multiply by exactly 1. */
|
|
174
|
+
declare const isAffine: (e: readonly number[]) => boolean;
|
|
175
|
+
/** `Vector3.applyMatrix4`. */
|
|
176
|
+
declare function transformPoint(e: readonly number[], x: number, y: number, z: number): [number, number, number];
|
|
177
|
+
/** The local matrix of a transform, or `null` when it has none. */
|
|
178
|
+
declare function matrixOf(t: Transform): Matrix4 | null;
|
|
179
|
+
|
|
180
|
+
interface ShapeCacheOptions {
|
|
181
|
+
/** Most results kept (default 256). */
|
|
182
|
+
readonly maxEntries?: number;
|
|
183
|
+
/** Most bytes of arrays kept (default 64 MiB). A result larger than this alone is not kept. */
|
|
184
|
+
readonly maxBytes?: number;
|
|
185
|
+
}
|
|
186
|
+
interface ShapeCacheStats {
|
|
187
|
+
readonly entries: number;
|
|
188
|
+
readonly bytes: number;
|
|
189
|
+
readonly hits: number;
|
|
190
|
+
readonly misses: number;
|
|
191
|
+
readonly evictions: number;
|
|
192
|
+
}
|
|
193
|
+
/** An LRU of results by `shapeKey`. What it returns is shared: read-only (copy with `cloneBuffers` before deforming). */
|
|
194
|
+
interface ShapeCache {
|
|
195
|
+
get(key: string): ShapeBuffers | undefined;
|
|
196
|
+
set(key: string, buffers: ShapeBuffers): void;
|
|
197
|
+
has(key: string): boolean;
|
|
198
|
+
delete(key: string): boolean;
|
|
199
|
+
clear(): void;
|
|
200
|
+
stats(): ShapeCacheStats;
|
|
201
|
+
}
|
|
202
|
+
/** An LRU of `ShapeBuffers` by key, bounded by entries and by bytes of the arrays. Pure memoisation: a hit gives the bytes a miss would. */
|
|
203
|
+
declare function createShapeCache(options?: ShapeCacheOptions): ShapeCache;
|
|
204
|
+
|
|
205
|
+
/** Anything with `postMessage` / `onmessage` / `terminate`: a browser `Worker`, a `worker_threads` wrapper, an in-thread fake. */
|
|
206
|
+
interface WorkerLike {
|
|
207
|
+
onmessage: ((event: {
|
|
208
|
+
data: unknown;
|
|
209
|
+
}) => void) | null;
|
|
210
|
+
onerror?: ((event: unknown) => void) | null;
|
|
211
|
+
postMessage(message: unknown, transfer?: ArrayBuffer[]): void;
|
|
212
|
+
terminate(): unknown;
|
|
213
|
+
}
|
|
214
|
+
interface ShapePoolOptions {
|
|
215
|
+
/** Workers (default 0: generate in the calling thread). */
|
|
216
|
+
readonly size?: number;
|
|
217
|
+
/** Makes one worker that runs `installShapeWorker`. Without it the pool generates in the calling thread. */
|
|
218
|
+
readonly spawn?: () => WorkerLike;
|
|
219
|
+
/** Results by `shapeKey`: a hit resolves at once and never reaches a worker. */
|
|
220
|
+
readonly cache?: ShapeCache;
|
|
221
|
+
/** Generators of the `custom` nodes for the jobs made in the calling thread (the workers register their own). */
|
|
222
|
+
readonly generators?: Readonly<Record<string, ShapeGenerator>>;
|
|
223
|
+
/** Look custom nodes up in `generators` only (for example `shapes.record()` of `createShapes`), never in the global registry; the jobs then run in the calling thread, since a worker cannot receive functions. */
|
|
224
|
+
readonly isolatedGenerators?: boolean;
|
|
225
|
+
}
|
|
226
|
+
interface ShapeRequest {
|
|
227
|
+
readonly schema: ShapeSchema;
|
|
228
|
+
readonly options?: GenerateOptions;
|
|
229
|
+
}
|
|
230
|
+
interface ShapePoolStats {
|
|
231
|
+
readonly workers: number;
|
|
232
|
+
readonly jobs: number;
|
|
233
|
+
readonly cacheHits: number;
|
|
234
|
+
readonly shared: number;
|
|
235
|
+
readonly inThread: number;
|
|
236
|
+
readonly busy: number;
|
|
237
|
+
}
|
|
238
|
+
interface ShapePool {
|
|
239
|
+
/** `generate(schema, options)` off the main thread. Same key, same promise while in flight; the result is shared (read-only). */
|
|
240
|
+
generate(schema: ShapeSchema, options?: GenerateOptions): Promise<ShapeBuffers>;
|
|
241
|
+
/** A list spread over the workers, resolved in input order. */
|
|
242
|
+
generateMany(list: readonly (ShapeSchema | ShapeRequest)[]): Promise<ShapeBuffers[]>;
|
|
243
|
+
stats(): ShapePoolStats;
|
|
244
|
+
/** Stops the workers; pending jobs reject. */
|
|
245
|
+
terminate(): void;
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* A pool of shape workers. The schema is cheap (plain data) and is built on the main thread; the buffers are generated in a worker and
|
|
249
|
+
* transferred back. With `size: 0` or no `spawn` it generates in the calling thread, with the same cache and in-flight sharing.
|
|
250
|
+
*/
|
|
251
|
+
declare function createShapePool(options?: ShapePoolOptions): ShapePool;
|
|
252
|
+
|
|
253
|
+
export { BevelSpec, Color, type DetailOptions, GenerateOptions, HoleSpec, type Matrix3, type Matrix4, type MergedArrays, PrimitiveBuffers, PrimitiveNode, RotationOrder, SHAPE_SCHEMA, ShapeBuffers, type ShapeCache, type ShapeCacheOptions, type ShapeCacheStats, ShapeGenerator, type ShapeGenerators, ShapeNode, ShapeOutline, type ShapePool, type ShapePoolOptions, type ShapePoolStats, type ShapeRequest, ShapeSchema, type Shapes, type ShapesOptions, Transform, type TransformedPiece, Vec3, type WorkerLike, assertValidShape, box, buildPrimitive, byteSizeOf, canonicalJson, circle, clearTemplateCache, cloneBuffers, clonePrimitive, colorChannels, colorHex, compose, computeVertexNormals, cone, createShapeCache, createShapePool, createShapes, cylinder, defaultShapeGenerators, difference, extrude, generate, getGenerator, hash64, hashValue, headingMatrix, identity4, isAffine, isPrimitiveNode, keyOptions, lathe, listGenerators, matrixOf, mergeTransformed, mulberry32, multiply, normalMatrix, plane, primitiveParameters, quaternionFromEuler, registerGenerator, ring, setTemplateCacheSize, shapeKey, sphere, srgbToLinear, streamFor, templateCacheStats, torus, transferablesOf, transformPoint, unregisterGenerator, validateShape };
|