@shaderfrog/core 2.0.1 → 3.0.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.
@@ -79,6 +79,7 @@ import importers from './importers';
79
79
  import { returnGlPositionHardCoded, returnGlPosition, returnGlPositionVec3Right, } from '../../util/ast';
80
80
  import { property, } from '../../graph/code-nodes';
81
81
  import { namedAttributeStrategy, texture2DStrategy, uniformStrategy, } from '../../strategy';
82
+ import indexById from '../../util/indexByid';
82
83
  var log = function () {
83
84
  var _a;
84
85
  var args = [];
@@ -126,12 +127,7 @@ export var defaultPropertySetting = function (app, property) {
126
127
  };
127
128
  var applyPlayMaterialProperties = function (engineContext, shaderMaterial, app, graph, node, sibling) {
128
129
  // Find inputs to this node that are dependent on a property of the material
129
- var propertyInputs = node.inputs
130
- .filter(function (i) { return i.property; })
131
- .reduce(function (acc, input) {
132
- var _a;
133
- return (__assign(__assign({}, acc), (_a = {}, _a[input.id] = input, _a)));
134
- }, {});
130
+ var propertyInputs = indexById(node.inputs.filter(function (i) { return i.property; }));
135
131
  // Then look for any edges into those inputs and set the material property
136
132
  var props = graph.edges
137
133
  .filter(function (edge) { return edge.to === node.id || edge.to === (sibling === null || sibling === void 0 ? void 0 : sibling.id); })
@@ -367,7 +363,7 @@ var onBeforeCompileMegaShader = function (engineContext, graph, node, sibling) {
367
363
  return [2 /*return*/, new Promise(function (resolve) {
368
364
  var variants = shaderMaterial.variants;
369
365
  if (variants.size === 1) {
370
- var _a = __read(variants.entries().next().value, 2), untypedVariant = _a[1];
366
+ var _a = __read(variants.entries().next().value || [], 2), untypedVariant = _a[1];
371
367
  var variant = untypedVariant;
372
368
  var _b = variant.definition, fshader = _b.fshader, vshader = _b.vshader;
373
369
  fragmentSource = fshader;
@@ -391,7 +387,7 @@ var onBeforeCompileMegaShader = function (engineContext, graph, node, sibling) {
391
387
  // TODO: NEED TO DO SAME THREE MANGLIGN STEP HERE
392
388
  var megaShaderMainpulateAst = function (engineContext, engine, graph, ast, inputEdges, node, sibling) {
393
389
  var programAst = ast;
394
- var mainName = 'main' || nodeName(node);
390
+ var mainName = nodeName(node);
395
391
  if (node.stage === 'vertex') {
396
392
  if (doesLinkThruShader(graph, node)) {
397
393
  returnGlPositionHardCoded(mainName, programAst, 'vec3', 'transformed');
@@ -491,7 +487,7 @@ export var playengine = {
491
487
  _b[NodeType.SOURCE] = {
492
488
  manipulateAst: function (engineContext, engine, graph, ast, inputEdges, node, sibling) {
493
489
  var programAst = ast;
494
- var mainName = 'main' || nodeName(node);
490
+ var mainName = nodeName(node);
495
491
  // This hinges on the vertex shader calling vec3(p)
496
492
  if (node.stage === 'vertex') {
497
493
  if (doesLinkThruShader(graph, node)) {
@@ -1,4 +1,4 @@
1
- import { RawShaderMaterial, Vector4, Color, Texture } from 'three';
1
+ import { RawShaderMaterial, Vector4, Color, Texture, Scene, WebGLRenderer, PerspectiveCamera } from 'three';
2
2
  import { ShaderStage } from '../../graph/graph-types';
3
3
  import { Engine, EngineContext } from '../../engine';
4
4
  import { CompileResult } from '../../graph/graph';
@@ -9,11 +9,12 @@ export declare const phongNode: (id: string, name: string, position: NodePositio
9
9
  export declare const physicalNode: (id: string, name: string, position: NodePosition, uniforms: UniformDataType[], stage: ShaderStage | undefined) => CodeNode;
10
10
  export declare const defaultPropertySetting: (property: NodeProperty) => 0.5 | Texture | Color | Vector4 | undefined;
11
11
  export type ThreeRuntime = {
12
- scene: any;
13
- camera: any;
14
- renderer: any;
12
+ scene: Scene;
13
+ camera: PerspectiveCamera;
14
+ renderer: WebGLRenderer;
15
15
  sceneData: any;
16
16
  engineMaterial: any;
17
+ loaded: boolean;
17
18
  index: number;
18
19
  cache: {
19
20
  data: {
@@ -29,6 +30,7 @@ export type ThreeRuntime = {
29
30
  };
30
31
  };
31
32
  };
33
+ export declare const stringifyThreeValue: (input: any) => string;
32
34
  export declare const toonNode: (id: string, name: string, position: NodePosition, uniforms: UniformDataType[], stage: ShaderStage | undefined) => CodeNode;
33
35
  export declare const threngine: Engine;
34
36
  export declare const createMaterial: (compileResult: CompileResult, ctx: EngineContext) => RawShaderMaterial;
@@ -76,10 +76,11 @@ import { NodeType } from '../../graph/graph-types';
76
76
  import { prepopulatePropertyInputs, mangleMainFn } from '../../graph/graph';
77
77
  import importers from './importers';
78
78
  import { EngineNodeType } from '../../engine';
79
- import { doesLinkThruShader, nodeName } from '../../graph/graph';
79
+ import { doesLinkThruShader } from '../../graph/graph';
80
80
  import { returnGlPosition, returnGlPositionHardCoded, returnGlPositionVec3Right, } from '../../util/ast';
81
81
  import { property, } from '../../graph/code-nodes';
82
82
  import { namedAttributeStrategy, texture2DStrategy, uniformStrategy, } from '../../strategy';
83
+ import indexById from '../../util/indexByid';
83
84
  var log = function () {
84
85
  var _a;
85
86
  var args = [];
@@ -117,6 +118,8 @@ export var phongNode = function (id, name, position, uniforms, stage) {
117
118
  property('Specular Map', 'specularMap', 'texture', 'filler_specularMap'),
118
119
  property('Displacement Map', 'displacementMap', 'texture', 'filler_displacementMap'),
119
120
  property('Displacement Scale', 'displacementScale', 'number'),
121
+ property('Bump Map', 'bumpMap', 'texture', 'filler_bumpMap'),
122
+ property('Bump Scale', 'bumpScale', 'number'),
120
123
  property('Env Map', 'envMap', 'samplerCube'),
121
124
  ],
122
125
  strategies: [
@@ -167,6 +170,7 @@ export var physicalNode = function (id, name, position, uniforms, stage) {
167
170
  // MeshPhysicalMaterial gets envMap from the scene. MeshStandardMaterial
168
171
  // gets it from the material
169
172
  // property('Env Map', 'envMap', 'samplerCube'),
173
+ property('Env Map Intensity', 'envMapIntensity', 'number', 'uniform_envMapIntensity'),
170
174
  property('Transmission', 'transmission', 'number'),
171
175
  property('Transmission Map', 'transmissionMap', 'texture', 'filler_transmissionMap'),
172
176
  property('Thickness', 'thickness', 'number'),
@@ -176,6 +180,7 @@ export var physicalNode = function (id, name, position, uniforms, stage) {
176
180
  // property('Sheen', 'sheen', 'number'),
177
181
  property('Reflectivity', 'reflectivity', 'number'),
178
182
  property('Clearcoat', 'clearcoat', 'number'),
183
+ property('Clearcoat Roughness', 'clearcoatRoughness', 'number'),
179
184
  property('Iridescence', 'iridescence', 'number'),
180
185
  property('Iridescence IOR', 'iridescenceIOR', 'number'),
181
186
  property('Iridescence Thickness Range', 'iridescenceThicknessRange', 'array', undefined, ['100', '400']),
@@ -213,17 +218,13 @@ var cacher = function (engineContext, graph, node, sibling, newValue) {
213
218
  log('Cache miss', cacheKey);
214
219
  }
215
220
  var materialData = engineContext.runtime.cache.data[cacheKey] || newValue();
221
+ // This is nasty: We mutate the runtime context here, and return the partial
222
+ // nodeContext later. See also the TODO: Refactor in context.ts.
216
223
  engineContext.runtime.cache.data[cacheKey] = materialData;
217
224
  engineContext.runtime.engineMaterial = materialData.material;
218
- // TODO: We mutate the nodes here, can we avoid that later?
219
- node.source =
220
- node.stage === 'fragment' ? materialData.fragment : materialData.vertex;
221
- if (sibling) {
222
- sibling.source =
223
- sibling.stage === 'fragment'
224
- ? materialData.fragment
225
- : materialData.vertex;
226
- }
225
+ return {
226
+ computedSource: node.stage === 'fragment' ? materialData.fragment : materialData.vertex,
227
+ };
227
228
  };
228
229
  var onBeforeCompileMegaShader = function (engineContext, newMat) {
229
230
  log('compiling three megashader!');
@@ -262,7 +263,7 @@ var onBeforeCompileMegaShader = function (engineContext, newMat) {
262
263
  };
263
264
  var megaShaderMainpulateAst = function (engineContext, engine, graph, ast, inputEdges, node, sibling) {
264
265
  var programAst = ast;
265
- var mainName = 'main' || nodeName(node);
266
+ var mainName = 'main'; // || nodeName(node);
266
267
  if (node.stage === 'vertex') {
267
268
  if (doesLinkThruShader(graph, node)) {
268
269
  returnGlPositionHardCoded(mainName, programAst, 'vec3', 'transformed');
@@ -292,6 +293,7 @@ var nodeCacheKey = function (graph, node) {
292
293
  );
293
294
  };
294
295
  var programCacheKey = function (engineContext, graph, node, sibling) {
296
+ var _a, _b;
295
297
  // The megashader source is dependent on scene information, like the number
296
298
  // and type of lights in the scene. This kinda sucks - it's duplicating
297
299
  // three's material cache key, and is coupled to how three builds shaders
@@ -299,7 +301,7 @@ var programCacheKey = function (engineContext, graph, node, sibling) {
299
301
  var lights = [];
300
302
  scene.traverse(function (obj) {
301
303
  if (obj instanceof Light) {
302
- lights.push(obj.type);
304
+ lights.push(obj.uuid);
303
305
  }
304
306
  });
305
307
  return ([node, sibling]
@@ -309,8 +311,10 @@ var programCacheKey = function (engineContext, graph, node, sibling) {
309
311
  .join('-') +
310
312
  '|Lights:' +
311
313
  lights.join(',') +
312
- '|Envtex:' +
313
- scene.environmentTexture);
314
+ '|Bg:' +
315
+ ((_a = scene.background) === null || _a === void 0 ? void 0 : _a.uuid) +
316
+ '|Env:' +
317
+ ((_b = scene.environment) === null || _b === void 0 ? void 0 : _b.uuid));
314
318
  };
315
319
  export var defaultPropertySetting = function (property) {
316
320
  if (property.type === 'texture') {
@@ -328,12 +332,7 @@ export var defaultPropertySetting = function (property) {
328
332
  };
329
333
  var threeMaterialProperties = function (graph, node, sibling) {
330
334
  // Find inputs to this node that are dependent on a property of the material
331
- var propertyInputs = node.inputs
332
- .filter(function (i) { return i.property; })
333
- .reduce(function (acc, input) {
334
- var _a;
335
- return (__assign(__assign({}, acc), (_a = {}, _a[input.id] = input, _a)));
336
- }, {});
335
+ var propertyInputs = indexById(node.inputs.filter(function (i) { return i.property; }));
337
336
  // Then look for any edges into those inputs and set the material property
338
337
  return graph.edges
339
338
  .filter(function (edge) { return edge.to === node.id || edge.to === (sibling === null || sibling === void 0 ? void 0 : sibling.id); })
@@ -349,6 +348,24 @@ var threeMaterialProperties = function (graph, node, sibling) {
349
348
  return acc;
350
349
  }, {});
351
350
  };
351
+ export var stringifyThreeValue = function (input) {
352
+ if (input instanceof Vector2) {
353
+ return "new Vector2(".concat(input.x, ", ").concat(input.y, ")");
354
+ }
355
+ else if (input instanceof Vector3) {
356
+ return "new Vector3(".concat(input.x, ", ").concat(input.y, ", ").concat(input.z, ")");
357
+ }
358
+ else if (input instanceof Vector4) {
359
+ return "new Vector4(".concat(input.x, ", ").concat(input.y, ", ").concat(input.z, ", ").concat(input.w, ")");
360
+ }
361
+ else if (input instanceof Color) {
362
+ return "new Color(".concat(input.r, ", ").concat(input.g, ", ").concat(input.b, ")");
363
+ }
364
+ else if (input instanceof Texture) {
365
+ return "new Texture()";
366
+ }
367
+ return "".concat(input);
368
+ };
352
369
  var evaluateNode = function (node) {
353
370
  if (node.type === 'number') {
354
371
  return parseFloat(node.value);
@@ -395,6 +412,7 @@ export var toonNode = function (id, name, position, uniforms, stage) {
395
412
  property('Displacement Map', 'displacementMap', 'texture', 'filler_displacementMap'),
396
413
  property('Displacement Scale', 'displacementScale', 'number'),
397
414
  property('Env Map', 'envMap', 'samplerCube'),
415
+ property('Env Map Intensity', 'envMapIntensity', 'number'),
398
416
  ],
399
417
  strategies: [
400
418
  uniformStrategy(),
@@ -459,6 +477,8 @@ export var threngine = {
459
477
  'shininess',
460
478
  'opacity',
461
479
  'map',
480
+ 'IncidentLight',
481
+ 'ReflectedLight',
462
482
  'specularTint',
463
483
  'normalScale',
464
484
  'normalMap',
@@ -510,7 +530,7 @@ export var threngine = {
510
530
  _b[NodeType.SOURCE] = {
511
531
  manipulateAst: function (engineContext, engine, graph, ast, inputEdges, node, sibling) {
512
532
  var programAst = ast;
513
- var mainName = 'main' || nodeName(node);
533
+ var mainName = 'main'; // || nodeName(node);
514
534
  // This hinges on the vertex shader calling vec3(p)
515
535
  if (node.stage === 'vertex') {
516
536
  if (doesLinkThruShader(graph, node)) {
@@ -526,12 +546,11 @@ export var threngine = {
526
546
  _b[EngineNodeType.phong] = {
527
547
  onBeforeCompile: function (graph, engineContext, node, sibling) { return __awaiter(void 0, void 0, void 0, function () {
528
548
  return __generator(this, function (_a) {
529
- cacher(engineContext, graph, node, sibling, function () {
530
- return onBeforeCompileMegaShader(engineContext, new MeshPhongMaterial(__assign({
531
- // @ts-ignore
532
- isMeshPhongMaterial: true }, threeMaterialProperties(graph, node, sibling))));
533
- });
534
- return [2 /*return*/];
549
+ return [2 /*return*/, cacher(engineContext, graph, node, sibling, function () {
550
+ return onBeforeCompileMegaShader(engineContext, new MeshPhongMaterial(__assign({
551
+ // @ts-ignore
552
+ isMeshPhongMaterial: true }, threeMaterialProperties(graph, node, sibling))));
553
+ })];
535
554
  });
536
555
  }); },
537
556
  manipulateAst: megaShaderMainpulateAst,
@@ -539,10 +558,9 @@ export var threngine = {
539
558
  _b[EngineNodeType.physical] = {
540
559
  onBeforeCompile: function (graph, engineContext, node, sibling) { return __awaiter(void 0, void 0, void 0, function () {
541
560
  return __generator(this, function (_a) {
542
- cacher(engineContext, graph, node, sibling, function () {
543
- return onBeforeCompileMegaShader(engineContext, new MeshPhysicalMaterial(__assign(__assign({}, node.config.hardCodedProperties), threeMaterialProperties(graph, node, sibling))));
544
- });
545
- return [2 /*return*/];
561
+ return [2 /*return*/, cacher(engineContext, graph, node, sibling, function () {
562
+ return onBeforeCompileMegaShader(engineContext, new MeshPhysicalMaterial(__assign(__assign({}, node.config.hardCodedProperties), threeMaterialProperties(graph, node, sibling))));
563
+ })];
546
564
  });
547
565
  }); },
548
566
  manipulateAst: megaShaderMainpulateAst,
@@ -550,12 +568,11 @@ export var threngine = {
550
568
  _b[EngineNodeType.toon] = {
551
569
  onBeforeCompile: function (graph, engineContext, node, sibling) { return __awaiter(void 0, void 0, void 0, function () {
552
570
  return __generator(this, function (_a) {
553
- cacher(engineContext, graph, node, sibling, function () {
554
- return onBeforeCompileMegaShader(engineContext, new MeshToonMaterial(__assign({ gradientMap: new Texture(),
555
- // @ts-ignore
556
- isMeshToonMaterial: true }, threeMaterialProperties(graph, node, sibling))));
557
- });
558
- return [2 /*return*/];
571
+ return [2 /*return*/, cacher(engineContext, graph, node, sibling, function () {
572
+ return onBeforeCompileMegaShader(engineContext, new MeshToonMaterial(__assign({ gradientMap: new Texture(),
573
+ // @ts-ignore
574
+ isMeshToonMaterial: true }, threeMaterialProperties(graph, node, sibling))));
575
+ })];
559
576
  });
560
577
  }); },
561
578
  manipulateAst: megaShaderMainpulateAst,
@@ -130,7 +130,6 @@ it('threngine shadertoy import', function () { return __awaiter(void 0, void 0,
130
130
  testImport = "\nvoid mainImage( out vec4 fragColor, in vec2 fragCoord ){\n vec3 rd = normalize(vec3(2.*fragCoord - iResolution.xy, iResolution.y));\n fragColor = vec4(sqrt(clamp(col, 0., 1.)), 1.0 * iTime);\n}\n";
131
131
  p = parser.parse(testImport);
132
132
  importers.shadertoy.convertAst(p, 'fragment');
133
- console.log(generate(p));
134
133
  expect(generate(p)).toContain("\nprecision highp float;\nprecision highp int;\n\nuniform vec2 mouse;\nuniform float time;\nuniform vec2 renderResolution;\n\nvoid main() {\n vec3 rd = normalize(vec3(2.*gl_FragCoord.xy - renderResolution.xy, renderResolution.y));\n gl_FragColor = vec4(sqrt(clamp(col, 0., 1.)), 1.0 * time);\n}\n");
135
134
  return [2 /*return*/];
136
135
  });
@@ -18,14 +18,13 @@ export var applyAssignmentToStrategy = function (strategy, ast, graphNode, sibli
18
18
  [
19
19
  nodeInput(name, "filler_".concat(name), 'filler', undefined, // Data type for what plugs into this filler
20
20
  ['code', 'data'], false),
21
- function (filler) {
22
- var filled = filler();
21
+ function (fillerAst) {
23
22
  if ('expression' in assignNode) {
24
23
  assignNode.expression.right =
25
- filled;
24
+ fillerAst;
26
25
  }
27
26
  else {
28
- assignNode.initializer = filled;
27
+ assignNode.initializer = fillerAst;
29
28
  }
30
29
  return ast;
31
30
  },
@@ -0,0 +1,10 @@
1
+ import { BaseStrategy, ApplyStrategy, StrategyType } from '.';
2
+ export interface AssignmentToStrategy extends BaseStrategy {
3
+ type: StrategyType.ASSIGNMENT_TO;
4
+ config: {
5
+ assignTo: string;
6
+ nth?: number;
7
+ };
8
+ }
9
+ export declare const assignemntToStrategy: (assignTo: string, nth?: number) => AssignmentToStrategy;
10
+ export declare const applyAssignmentToStrategy: ApplyStrategy<AssignmentToStrategy>;
@@ -0,0 +1,35 @@
1
+ import { findAssignmentTo } from '../util/ast';
2
+ import { nodeInput } from '../graph/base-node';
3
+ import { StrategyType } from '.';
4
+ // Constructor
5
+ export var assignemntToStrategy = function (assignTo, nth) {
6
+ if (nth === void 0) { nth = 1; }
7
+ return ({
8
+ type: StrategyType.ASSIGNMENT_TO,
9
+ config: { assignTo: assignTo, nth: nth },
10
+ });
11
+ };
12
+ // Apply the strategy
13
+ export var applyAssignmentToStrategy = function (strategy, ast, graphNode, siblingNode) {
14
+ var assignNode = findAssignmentTo(ast, strategy.config.assignTo, strategy.config.nth || 1);
15
+ var name = strategy.config.assignTo;
16
+ return assignNode
17
+ ? [
18
+ [
19
+ nodeInput(name, "filler_".concat(name), 'filler', undefined, // Data type for what plugs into this filler
20
+ ['code', 'data'], false),
21
+ function (filler) {
22
+ var filled = filler();
23
+ if ('expression' in assignNode) {
24
+ assignNode.expression.right =
25
+ filled;
26
+ }
27
+ else {
28
+ assignNode.initializer = filled;
29
+ }
30
+ return ast;
31
+ },
32
+ ],
33
+ ]
34
+ : [];
35
+ };
@@ -1,6 +1,6 @@
1
1
  export * from './hardCode';
2
2
  export * from './uniform';
3
- export * from './assignemntTo';
3
+ export * from './assignmentTo';
4
4
  export * from './inject';
5
5
  export * from './declarationOf';
6
6
  export * from './texture2D';
package/strategy/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  export * from './hardCode';
2
2
  export * from './uniform';
3
- export * from './assignemntTo';
3
+ export * from './assignmentTo';
4
4
  export * from './inject';
5
5
  export * from './declarationOf';
6
6
  export * from './texture2D';
@@ -2,7 +2,7 @@ import { AstNode, Program } from '@shaderfrog/glsl-parser/ast';
2
2
  import { SourceNode } from '../graph/code-nodes';
3
3
  import { HardCodeStrategy } from './hardCode';
4
4
  import { UniformStrategy } from './uniform';
5
- import { AssignemntToStrategy } from './assignemntTo';
5
+ import { AssignmentToStrategy } from './assignmentTo';
6
6
  import { DeclarationOfStrategy } from './declarationOf';
7
7
  import { Texture2DStrategy } from './texture2D';
8
8
  import { NamedAttributeStrategy } from './namedAttribute';
@@ -48,6 +48,6 @@ export interface BaseStrategy {
48
48
  type: StrategyType;
49
49
  config: Object;
50
50
  }
51
- export type Strategy = UniformStrategy | AssignemntToStrategy | Texture2DStrategy | NamedAttributeStrategy | VariableStrategy | HardCodeStrategy | InjectStrategy | DeclarationOfStrategy;
51
+ export type Strategy = UniformStrategy | AssignmentToStrategy | Texture2DStrategy | NamedAttributeStrategy | VariableStrategy | HardCodeStrategy | InjectStrategy | DeclarationOfStrategy;
52
52
  export type ApplyStrategy<T> = (strategy: T, ast: AstNode | Program, node: SourceNode, sibling?: SourceNode) => ComputedInput[];
53
53
  export declare const applyStrategy: (strategy: Strategy, ast: AstNode | Program, node: SourceNode, sibling?: SourceNode) => ComputedInput[];
@@ -1,7 +1,7 @@
1
1
  var _a;
2
2
  import { applyHardCodeStrategy } from './hardCode';
3
3
  import { applyUniformStrategy } from './uniform';
4
- import { applyAssignmentToStrategy, } from './assignemntTo';
4
+ import { applyAssignmentToStrategy, } from './assignmentTo';
5
5
  import { constApplyDeclarationOf as constApplyDeclarationOfStrategy, } from './declarationOf';
6
6
  import { applyTexture2DStrategy } from './texture2D';
7
7
  import { applyNamedAttributeStrategy, } from './namedAttribute';
package/util/ast.d.ts CHANGED
@@ -1,18 +1,19 @@
1
1
  /**
2
2
  * Utility functions to work with ASTs
3
3
  */
4
- import { AstNode, ExpressionStatementNode, FunctionNode, DeclarationStatementNode, DeclarationNode } from '@shaderfrog/glsl-parser/ast';
4
+ import { AstNode, ExpressionStatementNode, FunctionNode, DeclarationStatementNode, DeclarationNode, LiteralNode } from '@shaderfrog/glsl-parser/ast';
5
5
  import { Program } from '@shaderfrog/glsl-parser/ast';
6
6
  import { ShaderStage } from '../graph/graph-types';
7
7
  import { Scope } from '@shaderfrog/glsl-parser/parser/scope';
8
8
  export interface FrogProgram extends Program {
9
9
  outVar?: string;
10
10
  }
11
+ export declare const makeLiteral: (literal: string, whitespace?: string) => LiteralNode;
11
12
  export declare const findVec4Constructor: (ast: AstNode) => AstNode | undefined;
12
13
  export declare const findAssignmentTo: (ast: AstNode | Program, assignTo: string, nth?: number) => DeclarationNode | ExpressionStatementNode | undefined;
13
14
  export declare const findDeclarationOf: (ast: AstNode | Program, declarationOf: string) => DeclarationNode | undefined;
14
15
  export declare const from2To3: (ast: Program, stage: ShaderStage) => void;
15
- export declare const makeStatement: (stmt: string, ws?: string) => readonly [DeclarationStatementNode | FunctionNode | import("@shaderfrog/glsl-parser/ast").PreprocessorNode, Scope];
16
+ export declare const makeStatement: (stmt: string, ws?: string) => readonly [import("@shaderfrog/glsl-parser/ast").ProgramStatement, Scope];
16
17
  export declare const makeFnStatement: (fnStmt: string) => readonly [AstNode, Scope];
17
18
  /**
18
19
  * Add a new scope into an existing one. Meant to be used for adding net new
package/util/ast.js CHANGED
@@ -49,6 +49,14 @@ var log = function () {
49
49
  }
50
50
  return (_a = console.log).call.apply(_a, __spreadArray([console, '\x1b[31m(core.manipulate)\x1b[0m'], __read(args), false));
51
51
  };
52
+ export var makeLiteral = function (literal, whitespace) {
53
+ if (whitespace === void 0) { whitespace = ''; }
54
+ return ({
55
+ type: 'literal',
56
+ literal: literal,
57
+ whitespace: whitespace,
58
+ });
59
+ };
52
60
  export var findVec4Constructor = function (ast) {
53
61
  var parent;
54
62
  var visitors = {
@@ -0,0 +1,4 @@
1
+ declare const indexById: <T extends {
2
+ id: string | number;
3
+ }>(records: T[]) => Record<string, T>;
4
+ export default indexById;
@@ -0,0 +1,18 @@
1
+ var __assign = (this && this.__assign) || function () {
2
+ __assign = Object.assign || function(t) {
3
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
4
+ s = arguments[i];
5
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6
+ t[p] = s[p];
7
+ }
8
+ return t;
9
+ };
10
+ return __assign.apply(this, arguments);
11
+ };
12
+ var indexById = function (records) {
13
+ return records.reduce(function (acc, record) {
14
+ var _a;
15
+ return (__assign(__assign({}, acc), (_a = {}, _a[record.id] = record, _a)));
16
+ }, {});
17
+ };
18
+ export default indexById;
@@ -34,7 +34,7 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
34
34
  }
35
35
  return to.concat(ar || Array.prototype.slice.call(from));
36
36
  };
37
- import { makeFnStatement } from './ast';
37
+ import { makeFnStatement, makeLiteral } from './ast';
38
38
  var log = function () {
39
39
  var _a;
40
40
  var args = [];
@@ -88,17 +88,14 @@ export var addFnStmtWithIndent = function (fnBody, newNode) {
88
88
  return __spreadArray(__spreadArray([], __read(statements), false), [
89
89
  // This simple hack is way easier than trying to modify the function body
90
90
  // opening brace and/or the previous statement
91
- { type: 'literal', literal: '', whitespace: indent },
91
+ makeLiteral('', indent),
92
92
  addWs(newNode, "\n"),
93
93
  ], false);
94
94
  };
95
95
  export var unshiftFnStmtWithIndent = function (fnBody, newNode) {
96
96
  var statements = fnBody.body.statements;
97
97
  var indent = guessFnIndent(fnBody);
98
- return __spreadArray([
99
- addWs(newNode, "\n"),
100
- { type: 'literal', literal: '', whitespace: indent }
101
- ], __read(statements), false);
98
+ return __spreadArray([addWs(newNode, "\n"), makeLiteral('', indent)], __read(statements), false);
102
99
  };
103
100
  export var spliceFnStmtWithIndent = function (fnBody, index) {
104
101
  var newNodes = [];
@@ -108,10 +105,6 @@ export var spliceFnStmtWithIndent = function (fnBody, index) {
108
105
  var statements = fnBody.body.statements;
109
106
  var indent = guessFnIndent(fnBody);
110
107
  return __spreadArray(__spreadArray(__spreadArray(__spreadArray([], __read(statements.slice(0, index)), false), __read(newNodes.map(function (n) { return addWs(n, "\n"); })), false), [
111
- {
112
- type: 'literal',
113
- literal: '',
114
- whitespace: indent,
115
- }
108
+ makeLiteral('', indent)
116
109
  ], false), __read(statements.slice(index)), false);
117
110
  };