types.ts

examples/fxedit/fx/types.ts · raw · open the example · all examples · site home

Exports: PortTypeValueInputDefOptionDefNodeCategoryNodeSourceBuildContextNodeDefPORT_COMPONENTS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
// Node definitions: a TSL building block plus the metadata an editor needs
// (typed ports with defaults and UI ranges, options, attribution). A graph
// (graph.ts) wires nodes by id; buildGraphModifier (graphModifier.ts)
// builds it into a Radix SplatModifier.
import type { SplatNode, TslNode } from "@sparkjsdev/radix";

// Port types. color is a vec3 shown with a color picker; a bool param is a
// float uniform (above 0.5: true).
export type PortType = "float" | "vec2" | "vec3" | "vec4" | "color" | "bool";

export type Value = number | number[] | boolean;

export interface InputDef {
  type: PortType;
  default: Value;
  // Optional inputs are absent (build sees undefined) unless linked or given
  // a value in the graph; others become a param when unlinked
  optional?: boolean;
  // UI hints only
  min?: number;
  max?: number;
  step?: number;
  label?: string;
}

// Choices that change the program (enums, loop counts); part of the key
export interface OptionDef {
  default: string | number;
  choices?: string[];
  min?: number;
  max?: number;
}

// effect: whole effects ported as one node (macro nodes); group: instances
// of a graph's groups and their boundary nodes (graph.ts)
export type NodeCategory = "input" | "field" | "math" | "color" | "effect" | "group" | "splat";

export interface NodeSource {
  name: string;
  url: string;
  license: string;
}

export interface BuildContext {
  // Copy of the splat as it entered the graph (read it through input nodes)
  source: SplatNode;
  // The splat var the output node writes
  splat: SplatNode;
  // The stored splat's index (uint)
  index: TslNode;
  // Seconds (FxInputs.time), for nodes with `time: true`
  time: TslNode;
  // The last click (FxInputs.click) for nodes with `click: true`: its point
  // in the modifier's space and seconds since it
  click: { point: TslNode; age: TslNode };
  // The viewing camera (FxInputs.camera) for nodes with `camera: true`;
  // pixelSize: world size of one pixel at unit depth
  camera: { position: TslNode; forward: TslNode; pixelSize: TslNode };
  option(name: string): string | number;
}

export interface NodeDef {
  // Stable, namespaced: "field.noise"
  id: string;
  label: string;
  // One line for editors (palette, tooltips)
  description?: string;
  category: NodeCategory;
  inputs: Record<string, InputDef>;
  outputs: Record<string, PortType>;
  options?: Record<string, OptionDef>;
  // Reads ctx.time
  time?: boolean;
  // Reads ctx.click
  click?: boolean;
  // Reads ctx.camera (view-dependent: exact for one view per frame)
  camera?: boolean;
  // The graph's one output node (writes the splat; may return `keep`)
  output?: boolean;
  source?: NodeSource;
  build(inputs: Record<string, TslNode>, ctx: BuildContext): Record<string, TslNode>;
}

// Components of a port type's values (bool is one)
export const PORT_COMPONENTS: Record<PortType, number> = { float: 1, bool: 1, vec2: 2, vec3: 3, color: 3, vec4: 4 };