p5 2.2.1 → 2.2.2-rc.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.
Files changed (91) hide show
  1. package/dist/accessibility/color_namer.js +5 -5
  2. package/dist/accessibility/index.js +5 -5
  3. package/dist/app.js +5 -5
  4. package/dist/color/color_conversion.js +5 -5
  5. package/dist/color/index.js +1 -1
  6. package/dist/color/setting.js +1 -1
  7. package/dist/{constants-DQyACdzq.js → constants-D3npMLOW.js} +1 -1
  8. package/dist/core/constants.js +1 -1
  9. package/dist/core/environment.js +1 -1
  10. package/dist/core/filterShaders.js +1 -1
  11. package/dist/core/friendly_errors/fes_core.js +1 -1
  12. package/dist/core/friendly_errors/file_errors.js +1 -1
  13. package/dist/core/friendly_errors/index.js +1 -1
  14. package/dist/core/friendly_errors/param_validator.js +1 -1
  15. package/dist/core/friendly_errors/sketch_verifier.js +2 -2
  16. package/dist/core/helpers.js +1 -1
  17. package/dist/core/init.js +5 -5
  18. package/dist/core/internationalization.js +1 -1
  19. package/dist/core/legacy.js +5 -5
  20. package/dist/core/main.js +5 -5
  21. package/dist/core/p5.Graphics.js +3 -3
  22. package/dist/core/p5.Renderer.js +2 -2
  23. package/dist/core/p5.Renderer2D.js +5 -5
  24. package/dist/core/p5.Renderer3D.js +3 -3
  25. package/dist/core/rendering.js +3 -3
  26. package/dist/dom/dom.js +1 -1
  27. package/dist/dom/index.js +1 -1
  28. package/dist/dom/p5.Element.js +1 -1
  29. package/dist/dom/p5.MediaElement.js +1 -1
  30. package/dist/image/const.js +1 -1
  31. package/dist/image/filterRenderer2D.js +4 -4
  32. package/dist/image/image.js +3 -3
  33. package/dist/image/index.js +3 -3
  34. package/dist/image/loading_displaying.js +3 -3
  35. package/dist/image/p5.Image.js +2 -2
  36. package/dist/io/files.js +3 -3
  37. package/dist/io/index.js +3 -3
  38. package/dist/{ir_builders-DXNgaB9N.js → ir_builders-w12-GSxu.js} +37 -5
  39. package/dist/{main-DvN69W3f.js → main-C5AeICIY.js} +3 -3
  40. package/dist/math/Matrices/Matrix.js +1 -1
  41. package/dist/math/Matrices/MatrixNumjs.js +1 -1
  42. package/dist/math/index.js +1 -1
  43. package/dist/math/p5.Matrix.js +1 -1
  44. package/dist/math/p5.Vector.js +1 -1
  45. package/dist/math/trigonometry.js +1 -1
  46. package/dist/{p5.Renderer-D-5LdCRz.js → p5.Renderer-xpFkUQC6.js} +1 -1
  47. package/dist/{rendering-h9unX5K0.js → rendering-B8po3Onj.js} +57 -13
  48. package/dist/shape/2d_primitives.js +1 -1
  49. package/dist/shape/attributes.js +1 -1
  50. package/dist/shape/custom_shapes.js +1 -1
  51. package/dist/shape/index.js +1 -1
  52. package/dist/strands/ir_builders.js +1 -1
  53. package/dist/strands/p5.strands.js +1 -1
  54. package/dist/strands/strands_api.js +49 -18
  55. package/dist/strands/strands_conditionals.js +1 -1
  56. package/dist/strands/strands_for.js +2 -2
  57. package/dist/strands/strands_node.js +1 -1
  58. package/dist/type/index.js +2 -2
  59. package/dist/type/p5.Font.js +2 -2
  60. package/dist/type/textCore.js +2 -2
  61. package/dist/webgl/3d_primitives.js +3 -3
  62. package/dist/webgl/GeometryBuilder.js +1 -1
  63. package/dist/webgl/ShapeBuilder.js +1 -1
  64. package/dist/webgl/enums.js +1 -1
  65. package/dist/webgl/index.js +4 -4
  66. package/dist/webgl/interaction.js +1 -1
  67. package/dist/webgl/light.js +3 -3
  68. package/dist/webgl/loading.js +11 -13
  69. package/dist/webgl/material.js +3 -3
  70. package/dist/webgl/p5.Camera.js +3 -3
  71. package/dist/webgl/p5.Framebuffer.js +3 -3
  72. package/dist/webgl/p5.Geometry.js +1 -1
  73. package/dist/webgl/p5.Quat.js +1 -1
  74. package/dist/webgl/p5.RendererGL.js +4 -4
  75. package/dist/webgl/p5.Texture.js +3 -3
  76. package/dist/webgl/strands_glslBackend.js +1 -1
  77. package/dist/webgl/text.js +4 -4
  78. package/dist/webgl/utils.js +3 -3
  79. package/dist/webgpu/index.js +2 -2
  80. package/dist/webgpu/p5.RendererWebGPU.js +13 -4
  81. package/dist/webgpu/strands_wgslBackend.js +5 -4
  82. package/lib/p5.esm.js +152 -47
  83. package/lib/p5.esm.min.js +1 -1
  84. package/lib/p5.js +152 -47
  85. package/lib/p5.min.js +1 -1
  86. package/lib/p5.webgpu.esm.js +51 -9
  87. package/lib/p5.webgpu.js +51 -9
  88. package/lib/p5.webgpu.min.js +1 -1
  89. package/package.json +1 -1
  90. package/types/global.d.ts +1449 -1379
  91. package/types/p5.d.ts +727 -692
@@ -42,7 +42,7 @@ class StrandsNode {
42
42
  const baseType = orig?.baseType ?? BaseType.FLOAT;
43
43
 
44
44
  let newValueID;
45
- if (value instanceof StrandsNode) {
45
+ if (value?.isStrandsNode) {
46
46
  newValueID = value.id;
47
47
  } else {
48
48
  const newVal = primitiveConstructorNode(
@@ -97,7 +97,7 @@ class StrandsNode {
97
97
  const baseType = orig?.baseType ?? BaseType.FLOAT;
98
98
 
99
99
  let newValueID;
100
- if (value instanceof StrandsNode) {
100
+ if (value?.isStrandsNode) {
101
101
  newValueID = value.id;
102
102
  } else {
103
103
  const newVal = primitiveConstructorNode(
@@ -215,7 +215,7 @@ function unaryOpNode(strandsContext, nodeOrValue, opCode) {
215
215
  const { dag, cfg } = strandsContext;
216
216
  let dependsOn;
217
217
  let node;
218
- if (nodeOrValue instanceof StrandsNode) {
218
+ if (nodeOrValue?.isStrandsNode) {
219
219
  node = nodeOrValue;
220
220
  } else {
221
221
  const { id, dimension } = primitiveConstructorNode(strandsContext, { baseType: BaseType.FLOAT, dimension: null }, nodeOrValue);
@@ -429,6 +429,20 @@ function constructTypeFromIDs(strandsContext, typeInfo, strandsNodesArray) {
429
429
 
430
430
  function primitiveConstructorNode(strandsContext, typeInfo, dependsOn) {
431
431
  const cfg = strandsContext.cfg;
432
+ dependsOn = (Array.isArray(dependsOn) ? dependsOn : [dependsOn])
433
+ .flat(Infinity)
434
+ .map(a => {
435
+ if (
436
+ a.isStrandsNode &&
437
+ a.typeInfo().baseType === BaseType.INT &&
438
+ // TODO: handle ivec inputs instead of just int scalars
439
+ a.typeInfo().dimension === 1
440
+ ) {
441
+ return castToFloat(strandsContext, a);
442
+ } else {
443
+ return a;
444
+ }
445
+ });
432
446
  const { mappedDependencies, inferredTypeInfo } = mapPrimitiveDepsToIDs(strandsContext, typeInfo, dependsOn);
433
447
 
434
448
  const finalType = {
@@ -444,6 +458,24 @@ function primitiveConstructorNode(strandsContext, typeInfo, dependsOn) {
444
458
  return { id, dimension: finalType.dimension, components: mappedDependencies };
445
459
  }
446
460
 
461
+ function castToFloat(strandsContext, dep) {
462
+ const { id, dimension } = functionCallNode(
463
+ strandsContext,
464
+ strandsContext.backend.getTypeName('float', dep.typeInfo().dimension),
465
+ [dep],
466
+ {
467
+ overloads: [{
468
+ params: [dep.typeInfo()],
469
+ returnType: {
470
+ ...dep.typeInfo(),
471
+ baseType: BaseType.FLOAT,
472
+ },
473
+ }],
474
+ }
475
+ );
476
+ return createStrandsNode(id, dimension, strandsContext);
477
+ }
478
+
447
479
  function structConstructorNode(strandsContext, structTypeInfo, rawUserArgs) {
448
480
  const { cfg, dag } = strandsContext;
449
481
  const { identifer, properties } = structTypeInfo;
@@ -663,7 +695,7 @@ function swizzleTrap(id, dimension, strandsContext, onRebind) {
663
695
  // This may not be the most efficient way, as we swizzle each component individually,
664
696
  // so that .xyz becomes .x, .y, .z
665
697
  let scalars = [];
666
- if (value instanceof StrandsNode) {
698
+ if (value?.isStrandsNode) {
667
699
  if (value.dimension === 1) {
668
700
  scalars = Array(chars.length).fill(value);
669
701
  } else if (value.dimension === chars.length) {
@@ -722,4 +754,4 @@ function swizzleTrap(id, dimension, strandsContext, onRebind) {
722
754
  return trap;
723
755
  }
724
756
 
725
- export { StrandsNode as S, structInstanceNode as a, structConstructorNode as b, createStrandsNode as c, binaryOpNode as d, scalarLiteralNode as e, functionCallNode as f, constructTypeFromIDs as g, swizzleNode as h, swizzleTrap as i, memberAccessNode as m, primitiveConstructorNode as p, statementNode as s, unaryOpNode as u, variableNode as v };
757
+ export { StrandsNode as S, structInstanceNode as a, structConstructorNode as b, createStrandsNode as c, binaryOpNode as d, scalarLiteralNode as e, functionCallNode as f, constructTypeFromIDs as g, castToFloat as h, swizzleNode as i, swizzleTrap as j, memberAccessNode as m, primitiveConstructorNode as p, statementNode as s, unaryOpNode as u, variableNode as v };
@@ -1,9 +1,9 @@
1
- import { P as P2D, ac as WEBGL, B as BLEND, al as _DEFAULT_FILL, am as _DEFAULT_STROKE, w as ROUND, b as REMOVE, S as SUBTRACT, D as DARKEST, L as LIGHTEST, an as DIFFERENCE, M as MULTIPLY, E as EXCLUSION, a as SCREEN, R as REPLACE, ao as OVERLAY, ap as HARD_LIGHT, aq as SOFT_LIGHT, ar as DODGE, as as BURN, A as ADD, at as PIE, au as CHORD, q as TWO_PI, x as SQUARE, y as PROJECT, z as BEVEL, I as MITER, a9 as RIGHT, v as CENTER, av as LEFT, aw as BOTTOM, ax as BASELINE, ay as TOP, Q as OPEN, az as VERSION, a3 as constants } from './constants-DQyACdzq.js';
1
+ import { P as P2D, ac as WEBGL, B as BLEND, al as _DEFAULT_FILL, am as _DEFAULT_STROKE, w as ROUND, b as REMOVE, S as SUBTRACT, D as DARKEST, L as LIGHTEST, an as DIFFERENCE, M as MULTIPLY, E as EXCLUSION, a as SCREEN, R as REPLACE, ao as OVERLAY, ap as HARD_LIGHT, aq as SOFT_LIGHT, ar as DODGE, as as BURN, A as ADD, at as PIE, au as CHORD, q as TWO_PI, x as SQUARE, y as PROJECT, z as BEVEL, I as MITER, a9 as RIGHT, v as CENTER, av as LEFT, aw as BOTTOM, ax as BASELINE, ay as TOP, Q as OPEN, az as VERSION, a3 as constants } from './constants-D3npMLOW.js';
2
2
  import transform from './core/transform.js';
3
3
  import structure from './core/structure.js';
4
4
  import environment from './core/environment.js';
5
- import { G as Graphics, k as rendering, n as graphics } from './rendering-h9unX5K0.js';
6
- import { R as Renderer, I as Image, r as renderer } from './p5.Renderer-D-5LdCRz.js';
5
+ import { G as Graphics, k as rendering, n as graphics } from './rendering-B8po3Onj.js';
6
+ import { R as Renderer, I as Image, r as renderer } from './p5.Renderer-xpFkUQC6.js';
7
7
  import { Element } from './dom/p5.Element.js';
8
8
  import { MediaElement } from './dom/p5.MediaElement.js';
9
9
  import { b as RGBHDR } from './creating_reading-ZXzcZEsb.js';
@@ -1,6 +1,6 @@
1
1
  import { Vector } from '../p5.Vector.js';
2
2
  import { MatrixInterface } from './MatrixInterface.js';
3
- import '../../constants-DQyACdzq.js';
3
+ import '../../constants-D3npMLOW.js';
4
4
 
5
5
  /**
6
6
  * @module Math
@@ -1,7 +1,7 @@
1
1
  import nj from '@d4c/numjs/build/module/numjs.min.js';
2
2
  import { Vector } from '../p5.Vector.js';
3
3
  import { MatrixInterface } from './MatrixInterface.js';
4
- import '../../constants-DQyACdzq.js';
4
+ import '../../constants-D3npMLOW.js';
5
5
 
6
6
  let isMatrixArray = x => Array.isArray(x);
7
7
  if (typeof Float32Array !== 'undefined') {
@@ -4,7 +4,7 @@ import random from './random.js';
4
4
  import trigonometry from './trigonometry.js';
5
5
  import math$1 from './math.js';
6
6
  import vector from './p5.Vector.js';
7
- import '../constants-DQyACdzq.js';
7
+ import '../constants-D3npMLOW.js';
8
8
 
9
9
  function math(p5){
10
10
  p5.registerAddon(calculation);
@@ -1,6 +1,6 @@
1
1
  import { Matrix } from './Matrices/Matrix.js';
2
2
  import './p5.Vector.js';
3
- import '../constants-DQyACdzq.js';
3
+ import '../constants-D3npMLOW.js';
4
4
  import './Matrices/MatrixInterface.js';
5
5
 
6
6
  /**
@@ -1,4 +1,4 @@
1
- import { q as TWO_PI } from '../constants-DQyACdzq.js';
1
+ import { q as TWO_PI } from '../constants-D3npMLOW.js';
2
2
 
3
3
  /**
4
4
  * @module Math
@@ -1,4 +1,4 @@
1
- import { a5 as RAD_TO_DEG, a6 as DEG_TO_RAD } from '../constants-DQyACdzq.js';
1
+ import { a5 as RAD_TO_DEG, a6 as DEG_TO_RAD } from '../constants-D3npMLOW.js';
2
2
 
3
3
  /**
4
4
  * @module Math
@@ -1,5 +1,5 @@
1
1
  import { C as Color } from './creating_reading-ZXzcZEsb.js';
2
- import { a2 as NORMAL, aA as WORD, ax as BASELINE, av as LEFT, v as CENTER, p as CORNER, J as INCLUDE } from './constants-DQyACdzq.js';
2
+ import { a2 as NORMAL, aA as WORD, ax as BASELINE, av as LEFT, v as CENTER, p as CORNER, J as INCLUDE } from './constants-D3npMLOW.js';
3
3
  import Filters from './image/filters.js';
4
4
  import { Vector } from './math/p5.Vector.js';
5
5
  import { Shape } from './shape/custom_shapes.js';
@@ -1,7 +1,7 @@
1
- import { p as CORNER, t as CORNERS, v as CENTER, aB as COVER, aC as CONTAIN, a9 as RIGHT, aw as BOTTOM, B as BLEND, aD as FILL, ad as IMAGE, C as CLAMP, w as ROUND, Y as LINES, X as POINTS, c as TRIANGLES, ab as BLUR, D as DARKEST, L as LIGHTEST, A as ADD, S as SUBTRACT, a as SCREEN, E as EXCLUSION, R as REPLACE, M as MULTIPLY, b as REMOVE, as as BURN, ao as OVERLAY, ap as HARD_LIGHT, aq as SOFT_LIGHT, ar as DODGE, d as UNSIGNED_INT, U as UNSIGNED_BYTE, av as LEFT, ax as BASELINE, ay as TOP, aE as SIMPLE, aF as FULL, q as TWO_PI, Q as OPEN, a2 as NORMAL, V as CLOSE, at as PIE, au as CHORD, h as TEXTURE, P as P2D, g as LINEAR, aa as WEBGL2, N as NEAREST, aG as LINEAR_MIPMAP, f as REPEAT, e as MIRROR, F as FLOAT, ac as WEBGL, H as HALF_FLOAT } from './constants-DQyACdzq.js';
1
+ import { p as CORNER, t as CORNERS, v as CENTER, aB as COVER, aC as CONTAIN, a9 as RIGHT, aw as BOTTOM, B as BLEND, aD as FILL, ad as IMAGE, C as CLAMP, w as ROUND, Y as LINES, X as POINTS, c as TRIANGLES, ab as BLUR, D as DARKEST, L as LIGHTEST, A as ADD, S as SUBTRACT, a as SCREEN, E as EXCLUSION, R as REPLACE, M as MULTIPLY, b as REMOVE, as as BURN, ao as OVERLAY, ap as HARD_LIGHT, aq as SOFT_LIGHT, ar as DODGE, d as UNSIGNED_INT, U as UNSIGNED_BYTE, av as LEFT, ax as BASELINE, ay as TOP, aE as SIMPLE, aF as FULL, q as TWO_PI, Q as OPEN, a2 as NORMAL, V as CLOSE, at as PIE, au as CHORD, h as TEXTURE, P as P2D, g as LINEAR, aa as WEBGL2, N as NEAREST, aG as LINEAR_MIPMAP, f as REPEAT, e as MIRROR, F as FLOAT, ac as WEBGL, H as HALF_FLOAT } from './constants-D3npMLOW.js';
2
2
  import { C as Color, c as creatingReading, h as RGBA, R as RGB } from './creating_reading-ZXzcZEsb.js';
3
3
  import { Element } from './dom/p5.Element.js';
4
- import { R as Renderer, I as Image } from './p5.Renderer-D-5LdCRz.js';
4
+ import { R as Renderer, I as Image } from './p5.Renderer-xpFkUQC6.js';
5
5
  import { MediaElement } from './dom/p5.MediaElement.js';
6
6
  import primitives from './shape/2d_primitives.js';
7
7
  import attributes from './shape/attributes.js';
@@ -15104,6 +15104,40 @@ function material(p5, fn) {
15104
15104
  * }
15105
15105
  * ```
15106
15106
  *
15107
+ * We can use the `noise()` function built into strands to generate a color for each pixel. (Again no need here for underlying content for the filter to operate on.) Again we'll animate by passing in an announced uniform variable `time` with `setUniform()`, each frame.
15108
+ *
15109
+ * ```js example
15110
+ * let myFilter;
15111
+ *
15112
+ * function setup() {
15113
+ * createCanvas(100, 100, WEBGL);
15114
+ * myFilter = buildFilterShader(noiseShaderCallback);
15115
+ * describe('Evolving animated cloud-like noise in cyan and magenta');
15116
+ * }
15117
+ *
15118
+ * function noiseShaderCallback() {
15119
+ * let time = uniformFloat();
15120
+ * filterColor.begin();
15121
+ * let coord = filterColor.texCoord;
15122
+ *
15123
+ * //generate a value roughly between 0 and 1
15124
+ * let noiseVal = noise(coord.x, coord.y, time / 2000);
15125
+ *
15126
+ * let result = mix(
15127
+ * [1, 0, 1, 1], // Magenta
15128
+ * [0, 1, 1, 1], // Cyan
15129
+ * noiseVal
15130
+ * );
15131
+ * filterColor.set(result);
15132
+ * filterColor.end();
15133
+ * }
15134
+ *
15135
+ * function draw() {
15136
+ * myFilter.setUniform("time", millis());
15137
+ * filter(myFilter);
15138
+ * }
15139
+ * ```
15140
+ *
15107
15141
  * Like the `modify()` method on shaders,
15108
15142
  * advanced users can also fill in `filterColor` using <a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/3D_on_the_web/GLSL_Shaders" target="_blank">GLSL</a>
15109
15143
  * instead of JavaScript.
@@ -15118,15 +15152,17 @@ function material(p5, fn) {
15118
15152
  * @beta
15119
15153
  * @submodule p5.strands
15120
15154
  * @param {Function} callback A function building a p5.strands shader.
15155
+ * @param {Object} [scope] An optional scope object passed to .modify().
15121
15156
  * @returns {p5.Shader} The material shader
15122
15157
  */
15123
15158
  /**
15124
15159
  * @method buildFilterShader
15125
15160
  * @param {Object} hooks An object specifying p5.strands hooks in GLSL.
15161
+ * @param {Object} [scope] An optional scope object passed to .modify().
15126
15162
  * @returns {p5.Shader} The material shader
15127
15163
  */
15128
- fn.buildFilterShader = function (callback) {
15129
- return this.baseFilterShader().modify(callback);
15164
+ fn.buildFilterShader = function (callback, scope) {
15165
+ return this.baseFilterShader().modify(callback, scope);
15130
15166
  };
15131
15167
 
15132
15168
  /**
@@ -15946,15 +15982,17 @@ function material(p5, fn) {
15946
15982
  * @submodule p5.strands
15947
15983
  * @beta
15948
15984
  * @param {Function} callback A function building a p5.strands shader.
15985
+ * @param {Object} [scope] An optional scope object passed to .modify().
15949
15986
  * @returns {p5.Shader} The material shader.
15950
15987
  */
15951
15988
  /**
15952
15989
  * @method buildMaterialShader
15953
15990
  * @param {Object} hooks An object specifying p5.strands hooks in GLSL.
15991
+ * @param {Object} [scope] An optional scope object passed to .modify().
15954
15992
  * @returns {p5.Shader} The material shader.
15955
15993
  */
15956
- fn.buildMaterialShader = function (cb) {
15957
- return this.baseMaterialShader().modify(cb);
15994
+ fn.buildMaterialShader = function (cb, scope) {
15995
+ return this.baseMaterialShader().modify(cb, scope);
15958
15996
  };
15959
15997
 
15960
15998
  /**
@@ -16053,7 +16091,7 @@ function material(p5, fn) {
16053
16091
  /**
16054
16092
  * Returns the base shader used for filters.
16055
16093
  *
16056
- * Calling <a href="#/p5/buildMaterialShader">`buildFilterShader(shaderFunction)`</a>
16094
+ * Calling <a href="#/p5/buildFilterShader">`buildFilterShader(shaderFunction)`</a>
16057
16095
  * is equivalent to calling `baseFilterShader().modify(shaderFunction)`.
16058
16096
  *
16059
16097
  * Read <a href="#/p5/buildFilterShader">the `buildFilterShader` reference</a> or
@@ -16162,15 +16200,17 @@ function material(p5, fn) {
16162
16200
  * @submodule p5.strands
16163
16201
  * @beta
16164
16202
  * @param {Function} callback A function building a p5.strands shader.
16203
+ * @param {Object} [scope] An optional scope object passed to .modify().
16165
16204
  * @returns {p5.Shader} The normal shader.
16166
16205
  */
16167
16206
  /**
16168
16207
  * @method buildNormalShader
16169
16208
  * @param {Object} hooks An object specifying p5.strands hooks in GLSL.
16209
+ * @param {Object} [scope] An optional scope object passed to .modify().
16170
16210
  * @returns {p5.Shader} The normal shader.
16171
16211
  */
16172
- fn.buildNormalShader = function (cb) {
16173
- return this.baseNormalShader().modify(cb);
16212
+ fn.buildNormalShader = function (cb, scope) {
16213
+ return this.baseNormalShader().modify(cb, scope);
16174
16214
  };
16175
16215
 
16176
16216
  /**
@@ -16326,15 +16366,17 @@ function material(p5, fn) {
16326
16366
  * @submodule p5.strands
16327
16367
  * @beta
16328
16368
  * @param {Function} callback A function building a p5.strands shader.
16369
+ * @param {Object} [scope] An optional scope object passed to .modify().
16329
16370
  * @returns {p5.Shader} The color shader.
16330
16371
  */
16331
16372
  /**
16332
16373
  * @method buildColorShader
16333
16374
  * @param {Object} hooks An object specifying p5.strands hooks in GLSL.
16375
+ * @param {Object} [scope] An optional scope object passed to .modify().
16334
16376
  * @returns {p5.Shader} The color shader.
16335
16377
  */
16336
- fn.buildColorShader = function (cb) {
16337
- return this.baseColorShader().modify(cb);
16378
+ fn.buildColorShader = function (cb, scope) {
16379
+ return this.baseColorShader().modify(cb, scope);
16338
16380
  };
16339
16381
 
16340
16382
  /**
@@ -16581,15 +16623,17 @@ function material(p5, fn) {
16581
16623
  * @submodule p5.strands
16582
16624
  * @beta
16583
16625
  * @param {Function} callback A function building a p5.strands shader.
16626
+ * @param {Object} [scope] An optional scope object passed to .modify().
16584
16627
  * @returns {p5.Shader} The stroke shader.
16585
16628
  */
16586
16629
  /**
16587
16630
  * @method buildStrokeShader
16588
16631
  * @param {Object} hooks An object specifying p5.strands hooks in GLSL.
16632
+ * @param {Object} [scope] An optional scope object passed to .modify().
16589
16633
  * @returns {p5.Shader} The stroke shader.
16590
16634
  */
16591
- fn.buildStrokeShader = function (cb) {
16592
- return this.baseStrokeShader().modify(cb);
16635
+ fn.buildStrokeShader = function (cb, scope) {
16636
+ return this.baseStrokeShader().modify(cb, scope);
16593
16637
  };
16594
16638
 
16595
16639
  /**
@@ -1,4 +1,4 @@
1
- import { p as CORNER, q as TWO_PI, r as HALF_PI, s as PI } from '../constants-DQyACdzq.js';
1
+ import { p as CORNER, q as TWO_PI, r as HALF_PI, s as PI } from '../constants-D3npMLOW.js';
2
2
  import canvas from '../core/helpers.js';
3
3
 
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { p as CORNER, t as CORNERS, u as RADIUS, v as CENTER, w as ROUND, x as SQUARE, y as PROJECT, z as BEVEL, I as MITER } from '../constants-DQyACdzq.js';
1
+ import { p as CORNER, t as CORNERS, u as RADIUS, v as CENTER, w as ROUND, x as SQUARE, y as PROJECT, z as BEVEL, I as MITER } from '../constants-D3npMLOW.js';
2
2
 
3
3
  /**
4
4
  * @module Shape
@@ -1,6 +1,6 @@
1
1
  import { C as Color } from '../creating_reading-ZXzcZEsb.js';
2
2
  import { Vector } from '../math/p5.Vector.js';
3
- import { J as INCLUDE, K as PATH, O as EMPTY_PATH, Q as OPEN, V as CLOSE, X as POINTS, Y as LINES, c as TRIANGLES, Z as QUADS, _ as TRIANGLE_FAN, T as TRIANGLE_STRIP, $ as QUAD_STRIP, a0 as EXCLUDE, a1 as JOIN } from '../constants-DQyACdzq.js';
3
+ import { J as INCLUDE, K as PATH, O as EMPTY_PATH, Q as OPEN, V as CLOSE, X as POINTS, Y as LINES, c as TRIANGLES, Z as QUADS, _ as TRIANGLE_FAN, T as TRIANGLE_STRIP, $ as QUAD_STRIP, a0 as EXCLUDE, a1 as JOIN } from '../constants-D3npMLOW.js';
4
4
  import 'colorjs.io/fn';
5
5
  import '../color/color_spaces/hsb.js';
6
6
 
@@ -3,7 +3,7 @@ import attributes from './attributes.js';
3
3
  import curves from './curves.js';
4
4
  import vertex from './vertex.js';
5
5
  import customShapes from './custom_shapes.js';
6
- import '../constants-DQyACdzq.js';
6
+ import '../constants-D3npMLOW.js';
7
7
  import '../core/helpers.js';
8
8
  import '../creating_reading-ZXzcZEsb.js';
9
9
  import 'colorjs.io/fn';
@@ -2,5 +2,5 @@ import './ir_dag.js';
2
2
  import './ir_cfg.js';
3
3
  import './strands_FES.js';
4
4
  import './ir_types.js';
5
- export { d as binaryOpNode, g as constructTypeFromIDs, f as functionCallNode, m as memberAccessNode, p as primitiveConstructorNode, e as scalarLiteralNode, s as statementNode, b as structConstructorNode, a as structInstanceNode, h as swizzleNode, i as swizzleTrap, u as unaryOpNode, v as variableNode } from '../ir_builders-DXNgaB9N.js';
5
+ export { d as binaryOpNode, h as castToFloat, g as constructTypeFromIDs, f as functionCallNode, m as memberAccessNode, p as primitiveConstructorNode, e as scalarLiteralNode, s as statementNode, b as structConstructorNode, a as structInstanceNode, i as swizzleNode, j as swizzleTrap, u as unaryOpNode, v as variableNode } from '../ir_builders-w12-GSxu.js';
6
6
  import './strands_builtins.js';
@@ -8,7 +8,7 @@ import 'acorn';
8
8
  import 'acorn-walk';
9
9
  import 'escodegen';
10
10
  import './strands_FES.js';
11
- import '../ir_builders-DXNgaB9N.js';
11
+ import '../ir_builders-w12-GSxu.js';
12
12
  import './strands_builtins.js';
13
13
  import './strands_conditionals.js';
14
14
  import './strands_phi_utils.js';
@@ -1,4 +1,4 @@
1
- import { u as unaryOpNode, c as createStrandsNode, s as statementNode, v as variableNode, S as StrandsNode, p as primitiveConstructorNode, f as functionCallNode, a as structInstanceNode, b as structConstructorNode, d as binaryOpNode } from '../ir_builders-DXNgaB9N.js';
1
+ import { u as unaryOpNode, c as createStrandsNode, s as statementNode, v as variableNode, S as StrandsNode, p as primitiveConstructorNode, f as functionCallNode, a as structInstanceNode, b as structConstructorNode, d as binaryOpNode } from '../ir_builders-w12-GSxu.js';
2
2
  import { OperatorTable, StatementType, NodeType, DataType, BaseType, BlockType, isStructType, structType } from './ir_types.js';
3
3
  import { strandsBuiltinFunctions } from './strands_builtins.js';
4
4
  import { StrandsConditional } from './strands_conditionals.js';
@@ -43,7 +43,7 @@ function _getBuiltinGlobalsCache(strandsContext) {
43
43
  function getBuiltinGlobalNode(strandsContext, name) {
44
44
  const spec = BUILTIN_GLOBAL_SPECS[name];
45
45
  if (!spec) return null
46
-
46
+
47
47
  const cache = _getBuiltinGlobalsCache(strandsContext);
48
48
  const uniformName = `_p5_global_${name}`;
49
49
  const cached = cache.nodes.get(uniformName);
@@ -141,7 +141,7 @@ function initGlobalStrandsAPI(p5, fn, strandsContext) {
141
141
  }
142
142
 
143
143
  // Convert value to a StrandsNode if it isn't already
144
- const valueNode = value instanceof StrandsNode ? value : p5.strandsNode(value);
144
+ const valueNode = value?.isStrandsNode ? value : p5.strandsNode(value);
145
145
 
146
146
  // Create a new CFG block for the early return
147
147
  const earlyReturnBlockID = createBasicBlock(cfg, BlockType.DEFAULT);
@@ -356,12 +356,17 @@ function initGlobalStrandsAPI(p5, fn, strandsContext) {
356
356
  fn[typeInfo.fnName] = function(...args) {
357
357
  if (strandsContext.active) {
358
358
  if (args.length === 1 && args[0].dimension && args[0].dimension === typeInfo.dimension) {
359
- const { id, dimension } = functionCallNode(strandsContext, typeInfo.fnName, args, {
360
- overloads: [{
361
- params: [args[0].typeInfo()],
362
- returnType: typeInfo,
363
- }]
364
- });
359
+ const { id, dimension } = functionCallNode(
360
+ strandsContext,
361
+ strandsContext.backend.getTypeName(typeInfo.baseType, typeInfo.dimension),
362
+ args,
363
+ {
364
+ overloads: [{
365
+ params: [args[0].typeInfo()],
366
+ returnType: typeInfo,
367
+ }]
368
+ }
369
+ );
365
370
  return createStrandsNode(id, dimension, strandsContext);
366
371
  } else {
367
372
  // For vector types with a single argument, repeat it for each component
@@ -418,7 +423,7 @@ function createHookArguments(strandsContext, parameters){
418
423
  const oldDependsOn = dag.dependsOn[structNode.id];
419
424
  const newDependsOn = [...oldDependsOn];
420
425
  let newValueID;
421
- if (val instanceof StrandsNode) {
426
+ if (val?.isStrandsNode) {
422
427
  newValueID = val.id;
423
428
  }
424
429
  else {
@@ -450,7 +455,7 @@ function createHookArguments(strandsContext, parameters){
450
455
  return args;
451
456
  }
452
457
  function enforceReturnTypeMatch(strandsContext, expectedType, returned, hookName) {
453
- if (!(returned instanceof StrandsNode)) {
458
+ if (!(returned?.isStrandsNode)) {
454
459
  // try {
455
460
  const result = primitiveConstructorNode(strandsContext, expectedType, returned);
456
461
  return result.id;
@@ -472,7 +477,12 @@ function enforceReturnTypeMatch(strandsContext, expectedType, returned, hookName
472
477
  };
473
478
  if (receivedType.dimension !== expectedType.dimension) {
474
479
  if (receivedType.dimension !== 1) {
475
- userError('type error', `You have returned a vector with ${receivedType.dimension} components in ${hookName} when a ${expectedType.baseType + expectedType.dimension} was expected!`);
480
+ const receivedTypeDisplay = receivedType.baseType + (receivedType.dimension > 1 ? receivedType.dimension : '');
481
+ const expectedTypeDisplay = expectedType.baseType + expectedType.dimension;
482
+ userError('type error',
483
+ `You have returned a ${receivedTypeDisplay} in ${hookName} when a ${expectedTypeDisplay} was expected!\n\n` +
484
+ `Make sure your hook returns the correct type.`
485
+ );
476
486
  }
477
487
  else {
478
488
  const result = primitiveConstructorNode(strandsContext, expectedType, returned);
@@ -559,10 +569,27 @@ function createShaderHooksFunctions(strandsContext, fn, shader) {
559
569
  const handleRetVal = (retNode) => {
560
570
  if(isStructType(expectedReturnType)) {
561
571
  const expectedStructType = structType(expectedReturnType);
562
- if (retNode instanceof StrandsNode) {
572
+ if (retNode?.isStrandsNode) {
563
573
  const returnedNode = getNodeDataFromID(strandsContext.dag, retNode.id);
564
574
  if (returnedNode.baseType !== expectedStructType.typeName) {
565
- userError("type error", `You have returned a ${retNode.baseType} from ${hookType.name} when a ${expectedStructType.typeName} was expected.`);
575
+ const receivedTypeName = returnedNode.baseType || 'undefined';
576
+ const receivedDim = dag.dimensions[retNode.id];
577
+ const receivedTypeDisplay = receivedDim > 1 ?
578
+ `${receivedTypeName}${receivedDim}` : receivedTypeName;
579
+
580
+ const expectedProps = expectedStructType.properties
581
+ .map(p => p.name).join(', ');
582
+ userError('type error',
583
+ `You have returned a ${receivedTypeDisplay} from ${hookType.name} when a ${expectedStructType.typeName} was expected.\n\n` +
584
+ `The ${expectedStructType.typeName} struct has these properties: { ${expectedProps} }\n\n` +
585
+ `Instead of returning a different type, you should modify and return the ${expectedStructType.typeName} struct that was passed to your hook.\n\n` +
586
+ `For example:\n` +
587
+ `${hookType.name}((inputs) => {\n` +
588
+ ` // Modify properties of inputs\n` +
589
+ ` inputs.someProperty = ...;\n` +
590
+ ` return inputs; // Return the modified struct\n` +
591
+ `})`
592
+ );
566
593
  }
567
594
  const newDeps = returnedNode.dependsOn.slice();
568
595
  for (let i = 0; i < expectedStructType.properties.length; i++) {
@@ -581,10 +608,14 @@ function createShaderHooksFunctions(strandsContext, fn, shader) {
581
608
  const propName = expectedProp.name;
582
609
  const receivedValue = retNode[propName];
583
610
  if (receivedValue === undefined) {
584
- userError('type error', `You've returned an incomplete struct from ${hookType.name}.\n` +
585
- `Expected: { ${expectedReturnType.properties.map(p => p.name).join(', ')} }\n` +
586
- `Received: { ${Object.keys(retNode).join(', ')} }\n` +
587
- `All of the properties are required!`);
611
+ const expectedProps = expectedReturnType.properties.map(p => p.name).join(', ');
612
+ const receivedProps = Object.keys(retNode).join(', ');
613
+ userError('type error',
614
+ `You've returned an incomplete ${expectedStructType.typeName} struct from ${hookType.name}.\n\n` +
615
+ `Expected properties: { ${expectedProps} }\n` +
616
+ `Received properties: { ${receivedProps} }\n\n` +
617
+ `All properties are required! Make sure to include all properties in the returned struct.`
618
+ );
588
619
  }
589
620
  const expectedTypeInfo = expectedProp.dataType;
590
621
  const returnedPropID = enforceReturnTypeMatch(strandsContext, expectedTypeInfo, receivedValue, hookType.name);
@@ -1,7 +1,7 @@
1
1
  import { createBasicBlock, addEdge, pushBlock, popBlock, pushBlockForModification, recordInBasicBlock } from './ir_cfg.js';
2
2
  import { getOrCreateNode } from './ir_dag.js';
3
3
  import { BlockType, NodeType } from './ir_types.js';
4
- import { c as createStrandsNode } from '../ir_builders-DXNgaB9N.js';
4
+ import { c as createStrandsNode } from '../ir_builders-w12-GSxu.js';
5
5
  import { createPhiNode } from './strands_phi_utils.js';
6
6
  import './strands_FES.js';
7
7
  import './strands_builtins.js';
@@ -1,7 +1,7 @@
1
1
  import { createBasicBlock, addEdge, pushBlock, popBlock, pushBlockForModification, recordInBasicBlock } from './ir_cfg.js';
2
2
  import { getNodeDataFromID, createNodeData, getOrCreateNode } from './ir_dag.js';
3
3
  import { BlockType, NodeType, StatementType, OpCode, BaseType } from './ir_types.js';
4
- import { c as createStrandsNode, S as StrandsNode, p as primitiveConstructorNode } from '../ir_builders-DXNgaB9N.js';
4
+ import { c as createStrandsNode, p as primitiveConstructorNode } from '../ir_builders-w12-GSxu.js';
5
5
  import { createPhiNode } from './strands_phi_utils.js';
6
6
  import './strands_FES.js';
7
7
  import './strands_builtins.js';
@@ -310,7 +310,7 @@ class StrandsFor {
310
310
  let initialVar = this.initialCb();
311
311
 
312
312
  // Convert to StrandsNode if it's not already one
313
- if (!(initialVar instanceof StrandsNode)) {
313
+ if (!(initialVar?.isStrandsNode)) {
314
314
  const { id, dimension } = primitiveConstructorNode(this.strandsContext, { baseType: BaseType.FLOAT, dimension: 1 }, initialVar);
315
315
  initialVar = createStrandsNode(id, dimension, this.strandsContext);
316
316
  }
@@ -1,4 +1,4 @@
1
- export { S as StrandsNode, c as createStrandsNode } from '../ir_builders-DXNgaB9N.js';
1
+ export { S as StrandsNode, c as createStrandsNode } from '../ir_builders-w12-GSxu.js';
2
2
  import './ir_types.js';
3
3
  import './ir_dag.js';
4
4
  import './ir_cfg.js';
@@ -1,10 +1,10 @@
1
1
  import textCore from './textCore.js';
2
2
  import font from './p5.Font.js';
3
- import '../p5.Renderer-D-5LdCRz.js';
3
+ import '../p5.Renderer-xpFkUQC6.js';
4
4
  import '../creating_reading-ZXzcZEsb.js';
5
5
  import 'colorjs.io/fn';
6
6
  import '../color/color_spaces/hsb.js';
7
- import '../constants-DQyACdzq.js';
7
+ import '../constants-D3npMLOW.js';
8
8
  import '../image/filters.js';
9
9
  import '../math/p5.Vector.js';
10
10
  import '../shape/custom_shapes.js';
@@ -1,11 +1,11 @@
1
1
  import { textCoreConstants } from './textCore.js';
2
- import { v as CENTER, a9 as RIGHT, u as RADIUS } from '../constants-DQyACdzq.js';
2
+ import { v as CENTER, a9 as RIGHT, u as RADIUS } from '../constants-D3npMLOW.js';
3
3
  import { UnicodeRange } from '@japont/unicode-range';
4
4
  import { unicodeRanges } from './unicodeRanges.js';
5
5
  import { Vector } from '../math/p5.Vector.js';
6
6
  import Typr from './lib/Typr.js';
7
7
  import { createFromCommands } from '@davepagurek/bezier-path';
8
- import '../p5.Renderer-D-5LdCRz.js';
8
+ import '../p5.Renderer-xpFkUQC6.js';
9
9
  import '../creating_reading-ZXzcZEsb.js';
10
10
  import 'colorjs.io/fn';
11
11
  import '../color/color_spaces/hsb.js';
@@ -1,8 +1,8 @@
1
- import { R as Renderer } from '../p5.Renderer-D-5LdCRz.js';
1
+ import { R as Renderer } from '../p5.Renderer-xpFkUQC6.js';
2
2
  import '../creating_reading-ZXzcZEsb.js';
3
3
  import 'colorjs.io/fn';
4
4
  import '../color/color_spaces/hsb.js';
5
- import '../constants-DQyACdzq.js';
5
+ import '../constants-D3npMLOW.js';
6
6
  import '../image/filters.js';
7
7
  import '../math/p5.Vector.js';
8
8
  import '../shape/custom_shapes.js';
@@ -1,5 +1,5 @@
1
- import '../constants-DQyACdzq.js';
2
- export { p as default } from '../rendering-h9unX5K0.js';
1
+ import '../constants-D3npMLOW.js';
2
+ export { p as default } from '../rendering-B8po3Onj.js';
3
3
  import '../math/p5.Vector.js';
4
4
  import './p5.Geometry.js';
5
5
  import '../math/p5.Matrix.js';
@@ -10,7 +10,7 @@ import '../color/color_spaces/hsb.js';
10
10
  import '../dom/p5.Element.js';
11
11
  import '../dom/p5.File.js';
12
12
  import '../io/p5.XML.js';
13
- import '../p5.Renderer-D-5LdCRz.js';
13
+ import '../p5.Renderer-xpFkUQC6.js';
14
14
  import '../image/filters.js';
15
15
  import '../shape/custom_shapes.js';
16
16
  import '../core/States.js';
@@ -1,4 +1,4 @@
1
- import { T as TRIANGLE_STRIP, $ as QUAD_STRIP, _ as TRIANGLE_FAN, c as TRIANGLES } from '../constants-DQyACdzq.js';
1
+ import { T as TRIANGLE_STRIP, $ as QUAD_STRIP, _ as TRIANGLE_FAN, c as TRIANGLES } from '../constants-D3npMLOW.js';
2
2
  import '../math/p5.Matrix.js';
3
3
  import { Geometry } from './p5.Geometry.js';
4
4
  import { Matrix } from '../math/Matrices/Matrix.js';
@@ -1,4 +1,4 @@
1
- import { K as PATH, Z as QUADS, $ as QUAD_STRIP, T as TRIANGLE_STRIP, c as TRIANGLES, ad as IMAGE, Y as LINES, _ as TRIANGLE_FAN } from '../constants-DQyACdzq.js';
1
+ import { K as PATH, Z as QUADS, $ as QUAD_STRIP, T as TRIANGLE_STRIP, c as TRIANGLES, ad as IMAGE, Y as LINES, _ as TRIANGLE_FAN } from '../constants-D3npMLOW.js';
2
2
  import { Geometry } from './p5.Geometry.js';
3
3
  import libtess from 'libtess';
4
4
  import { Vector } from '../math/p5.Vector.js';
@@ -1,4 +1,4 @@
1
- import { a3 as constants } from '../constants-DQyACdzq.js';
1
+ import { a3 as constants } from '../constants-D3npMLOW.js';
2
2
 
3
3
  function getStrokeDefs(shaderConstant) {
4
4
  const STROKE_CAP_ENUM = {};