@aethervtt/shard-noise 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.
package/dist/graph.js ADDED
@@ -0,0 +1,370 @@
1
+ import { ShardError } from "@aethervtt/shard-core";
2
+ import { MAX_OCTAVES, nodeDef } from "./nodes.js";
3
+ function pointer(segment) {
4
+ return segment.replaceAll("~", "~0").replaceAll("/", "~1");
5
+ }
6
+ const fail = (code, path, message, hint) => new ShardError(code, message, { path, ...hint ? { hint } : {} });
7
+ function isObject(v) {
8
+ return typeof v === "object" && v !== null && !Array.isArray(v);
9
+ }
10
+ function parseGraph(json) {
11
+ const errors = [];
12
+ if (!isObject(json)) {
13
+ errors.push(
14
+ new ShardError("noise/invalid-graph", "A noise graph is a JSON object", {
15
+ path: "",
16
+ hint: 'Start from { "output": "height", "nodes": { \u2026 } }.'
17
+ })
18
+ );
19
+ return { errors };
20
+ }
21
+ for (const key of Object.keys(json)) {
22
+ if (!["$schema", "output", "nodes", "dimensions", "extent", "description"].includes(key)) {
23
+ errors.push(
24
+ fail(
25
+ "noise/invalid-graph",
26
+ `/${pointer(key)}`,
27
+ `Unknown graph field "${key}"`,
28
+ "Graph fields: output, nodes, dimensions, extent, description."
29
+ )
30
+ );
31
+ }
32
+ }
33
+ const dimensions = json.dimensions ?? 3;
34
+ if (dimensions !== 2 && dimensions !== 3 && dimensions !== 4) {
35
+ errors.push(fail("noise/invalid-graph", "/dimensions", '"dimensions" must be 2, 3, or 4'));
36
+ }
37
+ const dims = dimensions === 2 || dimensions === 4 ? dimensions : 3;
38
+ const extent = json.extent;
39
+ if (extent !== void 0 && (typeof extent !== "number" || !(extent > 0))) {
40
+ errors.push(
41
+ fail("noise/invalid-graph", "/extent", '"extent" must be a positive number of units')
42
+ );
43
+ }
44
+ if (json.description !== void 0 && typeof json.description !== "string") {
45
+ errors.push(fail("noise/invalid-graph", "/description", '"description" must be a string'));
46
+ }
47
+ const nodes = /* @__PURE__ */ new Map();
48
+ if (!isObject(json.nodes) || Object.keys(json.nodes).length === 0) {
49
+ errors.push(
50
+ fail(
51
+ "noise/invalid-graph",
52
+ "/nodes",
53
+ 'A graph needs a "nodes" object with at least one node',
54
+ 'Add "nodes": { "height": { "fbm": { "octaves": 5 } } }.'
55
+ )
56
+ );
57
+ } else {
58
+ for (const [name, body] of Object.entries(json.nodes)) {
59
+ const node = parseNode(body, `/nodes/${pointer(name)}`, dims, errors);
60
+ if (node) nodes.set(name, node);
61
+ }
62
+ }
63
+ const output = json.output;
64
+ if (typeof output !== "string") {
65
+ errors.push(
66
+ fail("noise/invalid-graph", "/output", '"output" must name the node the graph returns')
67
+ );
68
+ } else if (isObject(json.nodes) && !(output in json.nodes)) {
69
+ errors.push(
70
+ fail(
71
+ "noise/unknown-node",
72
+ "/output",
73
+ `"output" names "${output}", which isn't a node`,
74
+ hintFor(output, json.nodes)
75
+ )
76
+ );
77
+ }
78
+ if (isObject(json.nodes)) {
79
+ for (const node of nodes.values()) checkRefs(node, json.nodes, errors);
80
+ checkCycles(nodes, errors);
81
+ }
82
+ if (errors.length > 0) return { errors };
83
+ return {
84
+ graph: {
85
+ output,
86
+ dimensions: dims,
87
+ extent,
88
+ description: json.description,
89
+ nodes
90
+ },
91
+ errors
92
+ };
93
+ }
94
+ function hintFor(_name, nodes) {
95
+ const names = Object.keys(nodes);
96
+ return names.length > 0 ? `Nodes in this graph: ${names.join(", ")}.` : 'Add the node under "nodes".';
97
+ }
98
+ function parseInput(v, path, dims, errors) {
99
+ if (typeof v === "number") {
100
+ if (!Number.isFinite(v)) {
101
+ errors.push(
102
+ new ShardError("noise/invalid-param", "Numbers must be finite", {
103
+ path,
104
+ hint: "Check the parameter against .shard/schemas/noise.schema.json."
105
+ })
106
+ );
107
+ return void 0;
108
+ }
109
+ return { kind: "const", value: v };
110
+ }
111
+ if (typeof v === "string") return { kind: "ref", name: v, path };
112
+ if (isObject(v)) {
113
+ const node = parseNode(v, path, dims, errors);
114
+ return node ? { kind: "node", node } : void 0;
115
+ }
116
+ errors.push(
117
+ fail("noise/invalid-param", path, "An input is a node name, an inline node, or a number")
118
+ );
119
+ return void 0;
120
+ }
121
+ function parseNode(body, path, dims, errors) {
122
+ if (typeof body === "number") {
123
+ const def2 = nodeDef("constant");
124
+ return { type: "constant", def: def2, params: { value: body }, path };
125
+ }
126
+ if (!isObject(body) || Object.keys(body).length !== 1) {
127
+ errors.push(
128
+ new ShardError("noise/invalid-node", "A node is an object with exactly one key: its type", {
129
+ path,
130
+ hint: 'For example { "fbm": { "octaves": 5 } }.'
131
+ })
132
+ );
133
+ return void 0;
134
+ }
135
+ const [type, raw] = Object.entries(body)[0];
136
+ const def = nodeDef(type);
137
+ const at = `${path}/${pointer(type)}`;
138
+ if (!def) {
139
+ errors.push(
140
+ new ShardError("noise/unknown-type", `Unknown node type "${type}"`, {
141
+ path: at,
142
+ hint: "Types: value, perlin, simplex, cellular, fbm, ridged, billow, add, multiply, min, max, lerp, select, remap, clamp, curve, terrace, abs, power, constant, warp, scale, translate."
143
+ })
144
+ );
145
+ return void 0;
146
+ }
147
+ if (def.form === "value") {
148
+ if (typeof raw !== "number" || !Number.isFinite(raw)) {
149
+ errors.push(fail("noise/invalid-param", at, `"${type}" takes a number`));
150
+ return void 0;
151
+ }
152
+ return { type, def, params: { value: raw }, path: at };
153
+ }
154
+ if (def.form === "list") {
155
+ if (!Array.isArray(raw) || raw.length < 2) {
156
+ errors.push(
157
+ new ShardError("noise/arity", `"${type}" takes an array of two or more inputs`, {
158
+ path: at,
159
+ hint: 'Give it two or more inputs: node names, inline nodes, or numbers, e.g. ["a", "b"].'
160
+ })
161
+ );
162
+ return void 0;
163
+ }
164
+ const inputs = [];
165
+ raw.forEach((v, i) => {
166
+ const input = parseInput(v, `${at}/${i}`, dims, errors);
167
+ if (input) inputs.push(input);
168
+ });
169
+ return { type, def, params: { inputs }, path: at };
170
+ }
171
+ let fields;
172
+ if (def.form === "unary" && !isObject(raw)) fields = { input: raw };
173
+ else if (def.form === "unary" && isObject(raw) && !("input" in raw)) fields = { input: raw };
174
+ else if (isObject(raw)) fields = raw;
175
+ else {
176
+ errors.push(
177
+ fail(
178
+ "noise/invalid-node",
179
+ at,
180
+ `"${type}" takes an object of parameters`,
181
+ `Parameters: ${Object.keys(def.params).join(", ")}.`
182
+ )
183
+ );
184
+ return void 0;
185
+ }
186
+ const params = {};
187
+ for (const key of Object.keys(fields)) {
188
+ if (!(key in def.params)) {
189
+ errors.push(
190
+ fail(
191
+ "noise/invalid-param",
192
+ `${at}/${pointer(key)}`,
193
+ `"${type}" has no parameter "${key}"`,
194
+ `Parameters: ${Object.keys(def.params).join(", ")}.`
195
+ )
196
+ );
197
+ }
198
+ }
199
+ for (const [key, p] of Object.entries(def.params)) {
200
+ const value = parseParam(p, fields[key], `${at}/${pointer(key)}`, type, key, dims, errors);
201
+ if (value !== void 0) params[key] = value;
202
+ }
203
+ return { type, def, params, path: at };
204
+ }
205
+ function parseParam(p, v, path, type, key, dims, errors) {
206
+ const bad = (what) => {
207
+ errors.push(fail("noise/invalid-param", path, `"${type}.${key}" ${what}`, p.description));
208
+ return void 0;
209
+ };
210
+ if (v === void 0) {
211
+ if (p.type === "input") {
212
+ errors.push(fail("noise/arity", path, `"${type}" needs "${key}"`, p.description));
213
+ return void 0;
214
+ }
215
+ if (p.type === "points") {
216
+ errors.push(fail("noise/arity", path, `"${type}" needs "${key}"`, p.description));
217
+ return void 0;
218
+ }
219
+ if ("default" in p && p.default !== void 0) {
220
+ if (key === "dims" && dims === 2) return 2;
221
+ return p.default;
222
+ }
223
+ return void 0;
224
+ }
225
+ switch (p.type) {
226
+ case "input":
227
+ return parseInput(v, path, dims, errors);
228
+ case "number": {
229
+ if (typeof v !== "number" || !Number.isFinite(v)) return bad("must be a number");
230
+ if (p.positive && !(v > 0)) return bad("must be greater than 0");
231
+ if (p.min !== void 0 && v < p.min) return bad(`must be at least ${p.min}`);
232
+ if (p.max !== void 0 && v > p.max) return bad(`must be at most ${p.max}`);
233
+ return v;
234
+ }
235
+ case "integer": {
236
+ if (typeof v !== "number" || !Number.isInteger(v)) return bad("must be an integer");
237
+ if (key === "octaves" && v > MAX_OCTAVES) {
238
+ errors.push(
239
+ new ShardError(
240
+ "noise/too-many-octaves",
241
+ `"${type}" has ${v} octaves; the most is ${MAX_OCTAVES}`,
242
+ {
243
+ path,
244
+ hint: "Past 16 octaves the extra detail is below a pixel anywhere; raise frequency instead."
245
+ }
246
+ )
247
+ );
248
+ return void 0;
249
+ }
250
+ if (p.min !== void 0 && v < p.min) return bad(`must be at least ${p.min}`);
251
+ if (p.max !== void 0 && v > p.max) return bad(`must be at most ${p.max}`);
252
+ return v;
253
+ }
254
+ case "boolean":
255
+ return typeof v === "boolean" ? v : bad("must be true or false");
256
+ case "enum": {
257
+ if (!p.values.includes(v))
258
+ return bad(`must be one of ${p.values.join(", ")}`);
259
+ if (key === "dims" && v === 4 && dims !== 4) {
260
+ errors.push(
261
+ new ShardError("noise/domain-mismatch", `"${type}" is 4D but the graph is ${dims}D`, {
262
+ path,
263
+ hint: 'Set "dimensions": 4 on the graph and sample it with a w coordinate, or use dims 3.'
264
+ })
265
+ );
266
+ return void 0;
267
+ }
268
+ return v;
269
+ }
270
+ case "pair": {
271
+ if (!Array.isArray(v) || v.length !== 2 || !v.every((x) => typeof x === "number" && Number.isFinite(x))) {
272
+ return bad("must be [a, b]");
273
+ }
274
+ return v;
275
+ }
276
+ case "vec": {
277
+ if (typeof v === "number" && Number.isFinite(v)) return [v, v, v, v];
278
+ if (!Array.isArray(v) || v.length < 2 || v.length > 4 || !v.every((x) => typeof x === "number" && Number.isFinite(x))) {
279
+ return bad("must be a number or [x, y, z]");
280
+ }
281
+ const fill = key === "by" && type === "scale" ? 1 : 0;
282
+ return [v[0], v[1], v[2] ?? fill, v[3] ?? fill];
283
+ }
284
+ case "points": {
285
+ if (!Array.isArray(v) || v.length < 2) {
286
+ errors.push(
287
+ fail("noise/arity", path, `"${type}.${key}" needs at least two points`, p.description)
288
+ );
289
+ return void 0;
290
+ }
291
+ let last = -Infinity;
292
+ for (let i = 0; i < v.length; i++) {
293
+ const pt = v[i];
294
+ if (!Array.isArray(pt) || pt.length !== 2 || !pt.every((x) => typeof x === "number" && Number.isFinite(x))) {
295
+ errors.push(fail("noise/invalid-param", `${path}/${i}`, "A point is [x, y]"));
296
+ return void 0;
297
+ }
298
+ if (pt[0] <= last) {
299
+ errors.push(fail("noise/invalid-param", `${path}/${i}`, "Curve points need increasing x"));
300
+ return void 0;
301
+ }
302
+ last = pt[0];
303
+ }
304
+ return v;
305
+ }
306
+ }
307
+ }
308
+ function eachInput(node, f) {
309
+ for (const value of Object.values(node.params)) {
310
+ if (Array.isArray(value)) {
311
+ for (const v of value) if (isInput(v)) f(v);
312
+ } else if (isInput(value)) f(value);
313
+ }
314
+ }
315
+ function isInput(v) {
316
+ return isObject(v) && (v.kind === "ref" || v.kind === "node" || v.kind === "const");
317
+ }
318
+ function forEachInput(node, f) {
319
+ eachInput(node, f);
320
+ }
321
+ function checkRefs(node, names, errors) {
322
+ eachInput(node, (input) => {
323
+ if (input.kind === "ref" && !(input.name in names)) {
324
+ errors.push(
325
+ // Hint for the docs: name a node under "nodes", or add it there.
326
+ new ShardError("noise/unknown-node", `"${input.name}" isn't a node in this graph`, {
327
+ path: input.path,
328
+ hint: hintFor(input.name, names)
329
+ })
330
+ );
331
+ } else if (input.kind === "node") checkRefs(input.node, names, errors);
332
+ });
333
+ }
334
+ function checkCycles(nodes, errors) {
335
+ const state = /* @__PURE__ */ new Map();
336
+ const reported = /* @__PURE__ */ new Set();
337
+ const visit = (name, trail) => {
338
+ const s = state.get(name);
339
+ if (s === "done") return;
340
+ if (s === "visiting") {
341
+ const loop = trail.slice(trail.indexOf(name));
342
+ const key = [...loop].sort().join(">");
343
+ if (!reported.has(key)) {
344
+ reported.add(key);
345
+ errors.push(
346
+ new ShardError("noise/cycle", `Nodes form a cycle: ${[...loop, name].join(" \u2192 ")}`, {
347
+ path: `/nodes/${pointer(name)}`,
348
+ hint: "A node can\u2019t depend on itself; break the loop with a separate node."
349
+ })
350
+ );
351
+ }
352
+ return;
353
+ }
354
+ const node = nodes.get(name);
355
+ if (!node) return;
356
+ state.set(name, "visiting");
357
+ const walk = (n) => eachInput(n, (input) => {
358
+ if (input.kind === "ref") visit(input.name, [...trail, name]);
359
+ else if (input.kind === "node") walk(input.node);
360
+ });
361
+ walk(node);
362
+ state.set(name, "done");
363
+ };
364
+ for (const name of nodes.keys()) visit(name, []);
365
+ }
366
+ export {
367
+ forEachInput,
368
+ parseGraph,
369
+ pointer
370
+ };
@@ -0,0 +1,13 @@
1
+ export { compileGraph, FRACTAL, type NoiseProgram, OP, POSITION_REGS, SKEW, WIDTH, } from './compile.js';
2
+ export { NOISE_LIBRARY_PATH, registerNoiseGraph, registerNoiseLibrary } from './gpu.js';
3
+ export { forEachInput, type GraphInput, type GraphNode, type ParamValue, type ParsedGraph, parseGraph, pointer, } from './graph.js';
4
+ export { BLOCK, computeOrigins, directionToFace, faceToDirection, gridOrigin, gridPoints, ORIGIN_WORDS, type OriginTerms, patchOrigin, patchPoints, } from './kernel.js';
5
+ export { loadNoiseKernel, type NoiseKernel, noiseKernel, simdSupported, useNoiseKernel, } from './loader.js';
6
+ export { MAX_SAMPLE_POINTS, noiseMethods, resolveGraph } from './methods.js';
7
+ export { CELL_DISTANCES, CELL_RETURNS, MAX_OCTAVES, NODE_DEFS, type NodeCategory, type NodeDef, nodeDef, type ParamDef, SOURCE_KINDS, type SourceKind, } from './nodes.js';
8
+ export { NoiseGraph, type NoiseGraphArtifact, NoiseGraphAssetType, NoiseGraphImporter, NoiseGraphStore, NoiseGraphs, noiseNames, type ProgramJson, } from './noise-graph.js';
9
+ export { noisePlugin } from './plugin.js';
10
+ export { type AsyncOptions, type Grid2d, type GridParams, noiseOrigins, normalizeGrid, poolTiming, type SpherePatch, sampleGrid2d, sampleGrid2dAsync, sampleNoise, sampleNoiseAsync, sampleNoiseGradient, sampleOffset, sampleSpherePatch, sampleSpherePatchAsync, } from './sample.js';
11
+ export { noiseJsonSchema } from './schema.js';
12
+ export { type NoiseDomain, type NoisePreviewOptions, type NoiseStats, noiseStats, previewNoise, } from './stats.js';
13
+ export { generateWgsl, NOISE_LIBRARY, type WgslOptions } from './wgsl.js';
package/dist/index.js ADDED
@@ -0,0 +1,127 @@
1
+ import {
2
+ compileGraph,
3
+ FRACTAL,
4
+ OP,
5
+ POSITION_REGS,
6
+ SKEW,
7
+ WIDTH
8
+ } from "./compile.js";
9
+ import { NOISE_LIBRARY_PATH, registerNoiseGraph, registerNoiseLibrary } from "./gpu.js";
10
+ import {
11
+ forEachInput,
12
+ parseGraph,
13
+ pointer
14
+ } from "./graph.js";
15
+ import {
16
+ BLOCK,
17
+ computeOrigins,
18
+ directionToFace,
19
+ faceToDirection,
20
+ gridOrigin,
21
+ gridPoints,
22
+ ORIGIN_WORDS,
23
+ patchOrigin,
24
+ patchPoints
25
+ } from "./kernel.js";
26
+ import {
27
+ loadNoiseKernel,
28
+ noiseKernel,
29
+ simdSupported,
30
+ useNoiseKernel
31
+ } from "./loader.js";
32
+ import { MAX_SAMPLE_POINTS, noiseMethods, resolveGraph } from "./methods.js";
33
+ import {
34
+ CELL_DISTANCES,
35
+ CELL_RETURNS,
36
+ MAX_OCTAVES,
37
+ NODE_DEFS,
38
+ nodeDef,
39
+ SOURCE_KINDS
40
+ } from "./nodes.js";
41
+ import {
42
+ NoiseGraph,
43
+ NoiseGraphAssetType,
44
+ NoiseGraphImporter,
45
+ NoiseGraphStore,
46
+ NoiseGraphs,
47
+ noiseNames
48
+ } from "./noise-graph.js";
49
+ import { noisePlugin } from "./plugin.js";
50
+ import {
51
+ noiseOrigins,
52
+ normalizeGrid,
53
+ poolTiming,
54
+ sampleGrid2d,
55
+ sampleGrid2dAsync,
56
+ sampleNoise,
57
+ sampleNoiseAsync,
58
+ sampleNoiseGradient,
59
+ sampleOffset,
60
+ sampleSpherePatch,
61
+ sampleSpherePatchAsync
62
+ } from "./sample.js";
63
+ import { noiseJsonSchema } from "./schema.js";
64
+ import {
65
+ noiseStats,
66
+ previewNoise
67
+ } from "./stats.js";
68
+ import { generateWgsl, NOISE_LIBRARY } from "./wgsl.js";
69
+ export {
70
+ BLOCK,
71
+ CELL_DISTANCES,
72
+ CELL_RETURNS,
73
+ FRACTAL,
74
+ MAX_OCTAVES,
75
+ MAX_SAMPLE_POINTS,
76
+ NODE_DEFS,
77
+ NOISE_LIBRARY,
78
+ NOISE_LIBRARY_PATH,
79
+ NoiseGraph,
80
+ NoiseGraphAssetType,
81
+ NoiseGraphImporter,
82
+ NoiseGraphStore,
83
+ NoiseGraphs,
84
+ OP,
85
+ ORIGIN_WORDS,
86
+ POSITION_REGS,
87
+ SKEW,
88
+ SOURCE_KINDS,
89
+ WIDTH,
90
+ compileGraph,
91
+ computeOrigins,
92
+ directionToFace,
93
+ faceToDirection,
94
+ forEachInput,
95
+ generateWgsl,
96
+ gridOrigin,
97
+ gridPoints,
98
+ loadNoiseKernel,
99
+ nodeDef,
100
+ noiseJsonSchema,
101
+ noiseKernel,
102
+ noiseMethods,
103
+ noiseNames,
104
+ noiseOrigins,
105
+ noisePlugin,
106
+ noiseStats,
107
+ normalizeGrid,
108
+ parseGraph,
109
+ patchOrigin,
110
+ patchPoints,
111
+ pointer,
112
+ poolTiming,
113
+ previewNoise,
114
+ registerNoiseGraph,
115
+ registerNoiseLibrary,
116
+ resolveGraph,
117
+ sampleGrid2d,
118
+ sampleGrid2dAsync,
119
+ sampleNoise,
120
+ sampleNoiseAsync,
121
+ sampleNoiseGradient,
122
+ sampleOffset,
123
+ sampleSpherePatch,
124
+ sampleSpherePatchAsync,
125
+ simdSupported,
126
+ useNoiseKernel
127
+ };
@@ -0,0 +1,99 @@
1
+ // Types for kernel.js (plain JavaScript so worker threads can import it without a loader).
2
+
3
+ export declare const BLOCK: number
4
+ export declare const ORIGIN_WORDS: number
5
+
6
+ /** How each source octave's lattice position depends on the sample origin. */
7
+ export interface OriginTerms {
8
+ /** Per term, xyzw: frequency × domain scale (f32 values). */
9
+ readonly a: Float64Array
10
+ /** Per term, xyzw: frequency × domain offset (f64). */
11
+ readonly b: Float64Array
12
+ /** Per term: 0 (none), 2, 3, or 4 (the simplex skew for that many dimensions). */
13
+ readonly skew: Uint8Array
14
+ }
15
+
16
+ /** What `evalProgram` needs from a compiled program. */
17
+ export interface ProgramData {
18
+ readonly code: Int32Array
19
+ readonly consts: Float32Array
20
+ readonly registers: number
21
+ readonly result: number
22
+ }
23
+
24
+ export interface KernelState {
25
+ readonly memory: WebAssembly.Memory
26
+ }
27
+
28
+ export interface SpherePatch {
29
+ /** Cube face: 0 +X, 1 −X, 2 +Y, 3 −Y, 4 +Z, 5 −Z. */
30
+ readonly face: number
31
+ /** Lower corner in face coordinates, [-1, 1]. */
32
+ readonly x0: number
33
+ readonly y0: number
34
+ /** Side length in face coordinates (2 is the whole face). */
35
+ readonly extent: number
36
+ /** Vertices per side, edges included. */
37
+ readonly resolution: number
38
+ readonly radius: number
39
+ }
40
+
41
+ export interface Grid2d {
42
+ /** Lower corner. */
43
+ readonly origin: readonly [number, number]
44
+ readonly size: readonly [number, number]
45
+ /** Samples per side, edges included. */
46
+ readonly resolution: readonly [number, number]
47
+ /** The plane's z. Default 0. */
48
+ readonly z?: number
49
+ }
50
+
51
+ export declare function computeOrigins(
52
+ terms: OriginTerms,
53
+ origin: ArrayLike<number>,
54
+ out: Int32Array,
55
+ ): Int32Array
56
+ export declare function instantiate(
57
+ module: WebAssembly.Module,
58
+ instance?: WebAssembly.Instance,
59
+ ): KernelState
60
+ export declare function evalProgram(
61
+ state: KernelState,
62
+ program: ProgramData,
63
+ seed: number,
64
+ origins: Int32Array,
65
+ pts: ArrayLike<number>,
66
+ stride: number,
67
+ count: number,
68
+ out: Float32Array,
69
+ outOffset?: number,
70
+ ): void
71
+ export declare function faceToDirection<T extends { [i: number]: number }>(
72
+ face: number,
73
+ u: number,
74
+ v: number,
75
+ out: T,
76
+ offset?: number,
77
+ ): T
78
+ export declare function directionToFace(
79
+ x: number,
80
+ y: number,
81
+ z: number,
82
+ out: { [i: number]: number },
83
+ ): number
84
+ export declare function patchOrigin(p: SpherePatch, out: Float64Array): Float64Array
85
+ export declare function patchPoints(
86
+ p: SpherePatch,
87
+ origin: ArrayLike<number>,
88
+ row0: number,
89
+ row1: number,
90
+ out: Float32Array,
91
+ ): Float32Array
92
+ export declare function gridOrigin(g: Grid2d, out: Float64Array): Float64Array
93
+ export declare function gridPoints(
94
+ g: Grid2d,
95
+ origin: ArrayLike<number>,
96
+ row0: number,
97
+ row1: number,
98
+ out: Float32Array,
99
+ ): Float32Array