p5 2.2.1 → 2.2.2-rc.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.
Files changed (94) hide show
  1. package/dist/accessibility/color_namer.js +6 -6
  2. package/dist/accessibility/index.js +6 -6
  3. package/dist/app.js +6 -6
  4. package/dist/color/color_conversion.js +6 -6
  5. package/dist/color/creating_reading.js +1 -1
  6. package/dist/color/index.js +2 -2
  7. package/dist/color/p5.Color.js +1 -1
  8. package/dist/color/setting.js +2 -2
  9. package/dist/{constants-DQyACdzq.js → constants-DAnmXDew.js} +1 -1
  10. package/dist/core/constants.js +1 -1
  11. package/dist/core/environment.js +1 -1
  12. package/dist/core/filterShaders.js +1 -1
  13. package/dist/core/friendly_errors/fes_core.js +1 -1
  14. package/dist/core/friendly_errors/file_errors.js +1 -1
  15. package/dist/core/friendly_errors/index.js +1 -1
  16. package/dist/core/friendly_errors/param_validator.js +1 -1
  17. package/dist/core/friendly_errors/sketch_verifier.js +2 -2
  18. package/dist/core/helpers.js +1 -1
  19. package/dist/core/init.js +6 -6
  20. package/dist/core/internationalization.js +1 -1
  21. package/dist/core/legacy.js +6 -6
  22. package/dist/core/main.js +6 -6
  23. package/dist/core/p5.Graphics.js +4 -4
  24. package/dist/core/p5.Renderer.js +3 -3
  25. package/dist/core/p5.Renderer2D.js +6 -6
  26. package/dist/core/p5.Renderer3D.js +4 -4
  27. package/dist/core/rendering.js +4 -4
  28. package/dist/{creating_reading-ZXzcZEsb.js → creating_reading-C7hu6sg1.js} +2 -2
  29. package/dist/dom/dom.js +2 -2
  30. package/dist/dom/index.js +2 -2
  31. package/dist/dom/p5.Element.js +2 -2
  32. package/dist/dom/p5.MediaElement.js +2 -2
  33. package/dist/image/const.js +1 -1
  34. package/dist/image/filterRenderer2D.js +5 -5
  35. package/dist/image/image.js +4 -4
  36. package/dist/image/index.js +4 -4
  37. package/dist/image/loading_displaying.js +4 -4
  38. package/dist/image/p5.Image.js +3 -3
  39. package/dist/io/files.js +4 -4
  40. package/dist/io/index.js +4 -4
  41. package/dist/{ir_builders-DXNgaB9N.js → ir_builders-w12-GSxu.js} +37 -5
  42. package/dist/{main-DvN69W3f.js → main-E-swj5tF.js} +4 -4
  43. package/dist/math/Matrices/Matrix.js +1 -1
  44. package/dist/math/Matrices/MatrixNumjs.js +1 -1
  45. package/dist/math/index.js +1 -1
  46. package/dist/math/p5.Matrix.js +1 -1
  47. package/dist/math/p5.Vector.js +1 -1
  48. package/dist/math/trigonometry.js +1 -1
  49. package/dist/{p5.Renderer-D-5LdCRz.js → p5.Renderer-DOk9UW65.js} +2 -2
  50. package/dist/{rendering-h9unX5K0.js → rendering-B8V5Zt4k.js} +58 -14
  51. package/dist/shape/2d_primitives.js +1 -1
  52. package/dist/shape/attributes.js +1 -1
  53. package/dist/shape/custom_shapes.js +2 -2
  54. package/dist/shape/index.js +2 -2
  55. package/dist/strands/ir_builders.js +1 -1
  56. package/dist/strands/p5.strands.js +1 -1
  57. package/dist/strands/strands_api.js +91 -31
  58. package/dist/strands/strands_conditionals.js +1 -1
  59. package/dist/strands/strands_for.js +2 -2
  60. package/dist/strands/strands_node.js +1 -1
  61. package/dist/type/index.js +3 -3
  62. package/dist/type/p5.Font.js +3 -3
  63. package/dist/type/textCore.js +3 -3
  64. package/dist/webgl/3d_primitives.js +4 -4
  65. package/dist/webgl/GeometryBuilder.js +1 -1
  66. package/dist/webgl/ShapeBuilder.js +1 -1
  67. package/dist/webgl/enums.js +1 -1
  68. package/dist/webgl/index.js +5 -5
  69. package/dist/webgl/interaction.js +1 -1
  70. package/dist/webgl/light.js +4 -4
  71. package/dist/webgl/loading.js +12 -14
  72. package/dist/webgl/material.js +4 -4
  73. package/dist/webgl/p5.Camera.js +4 -4
  74. package/dist/webgl/p5.Framebuffer.js +4 -4
  75. package/dist/webgl/p5.Geometry.js +1 -1
  76. package/dist/webgl/p5.Quat.js +1 -1
  77. package/dist/webgl/p5.RendererGL.js +5 -5
  78. package/dist/webgl/p5.Texture.js +4 -4
  79. package/dist/webgl/strands_glslBackend.js +1 -1
  80. package/dist/webgl/text.js +5 -5
  81. package/dist/webgl/utils.js +4 -4
  82. package/dist/webgpu/index.js +2 -2
  83. package/dist/webgpu/p5.RendererWebGPU.js +13 -4
  84. package/dist/webgpu/strands_wgslBackend.js +5 -4
  85. package/lib/p5.esm.js +196 -62
  86. package/lib/p5.esm.min.js +1 -1
  87. package/lib/p5.js +196 -62
  88. package/lib/p5.min.js +1 -1
  89. package/lib/p5.webgpu.esm.js +51 -9
  90. package/lib/p5.webgpu.js +51 -9
  91. package/lib/p5.webgpu.min.js +1 -1
  92. package/package.json +1 -1
  93. package/types/global.d.ts +1453 -1383
  94. package/types/p5.d.ts +729 -694
package/lib/p5.js CHANGED
@@ -1,4 +1,4 @@
1
- /*! p5.js v2.2.1 February 11, 2026 */
1
+ /*! p5.js v2.2.2-rc.1 February 19, 2026 */
2
2
  var p5 = (function () {
3
3
  'use strict';
4
4
 
@@ -15,7 +15,7 @@ var p5 = (function () {
15
15
  * @property {String} VERSION
16
16
  * @final
17
17
  */
18
- const VERSION = '2.2.1';
18
+ const VERSION = '2.2.2-rc.1';
19
19
 
20
20
  // GRAPHICS RENDERER
21
21
  /**
@@ -12614,11 +12614,11 @@ var p5 = (function () {
12614
12614
  * values. 0 is equal to the first color, 0.1 is very near the first color,
12615
12615
  * 0.5 is halfway between the two colors, and so on. Negative numbers are set
12616
12616
  * to 0. Numbers greater than 1 are set to 1. This differs from the behavior of
12617
- * <a href="#/lerp">lerp</a>. It's necessary because numbers outside of the
12617
+ * <a href="#/p5/lerp">lerp</a>. It's necessary because numbers outside of the
12618
12618
  * interval [0, 1] will produce strange and unexpected colors.
12619
12619
  *
12620
12620
  * The way that colors are interpolated depends on the current
12621
- * <a href="#/colorMode">colorMode()</a>.
12621
+ * <a href="#/p5/colorMode">colorMode()</a>.
12622
12622
  *
12623
12623
  * @method lerpColor
12624
12624
  * @param {p5.Color} c1 interpolate from this color.
@@ -61240,6 +61240,40 @@ var p5 = (function () {
61240
61240
  * }
61241
61241
  * ```
61242
61242
  *
61243
+ * 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.
61244
+ *
61245
+ * ```js example
61246
+ * let myFilter;
61247
+ *
61248
+ * function setup() {
61249
+ * createCanvas(100, 100, WEBGL);
61250
+ * myFilter = buildFilterShader(noiseShaderCallback);
61251
+ * describe('Evolving animated cloud-like noise in cyan and magenta');
61252
+ * }
61253
+ *
61254
+ * function noiseShaderCallback() {
61255
+ * let time = uniformFloat();
61256
+ * filterColor.begin();
61257
+ * let coord = filterColor.texCoord;
61258
+ *
61259
+ * //generate a value roughly between 0 and 1
61260
+ * let noiseVal = noise(coord.x, coord.y, time / 2000);
61261
+ *
61262
+ * let result = mix(
61263
+ * [1, 0, 1, 1], // Magenta
61264
+ * [0, 1, 1, 1], // Cyan
61265
+ * noiseVal
61266
+ * );
61267
+ * filterColor.set(result);
61268
+ * filterColor.end();
61269
+ * }
61270
+ *
61271
+ * function draw() {
61272
+ * myFilter.setUniform("time", millis());
61273
+ * filter(myFilter);
61274
+ * }
61275
+ * ```
61276
+ *
61243
61277
  * Like the `modify()` method on shaders,
61244
61278
  * 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>
61245
61279
  * instead of JavaScript.
@@ -61254,15 +61288,17 @@ var p5 = (function () {
61254
61288
  * @beta
61255
61289
  * @submodule p5.strands
61256
61290
  * @param {Function} callback A function building a p5.strands shader.
61291
+ * @param {Object} [scope] An optional scope object passed to .modify().
61257
61292
  * @returns {p5.Shader} The material shader
61258
61293
  */
61259
61294
  /**
61260
61295
  * @method buildFilterShader
61261
61296
  * @param {Object} hooks An object specifying p5.strands hooks in GLSL.
61297
+ * @param {Object} [scope] An optional scope object passed to .modify().
61262
61298
  * @returns {p5.Shader} The material shader
61263
61299
  */
61264
- fn.buildFilterShader = function (callback) {
61265
- return this.baseFilterShader().modify(callback);
61300
+ fn.buildFilterShader = function (callback, scope) {
61301
+ return this.baseFilterShader().modify(callback, scope);
61266
61302
  };
61267
61303
 
61268
61304
  /**
@@ -62082,15 +62118,17 @@ var p5 = (function () {
62082
62118
  * @submodule p5.strands
62083
62119
  * @beta
62084
62120
  * @param {Function} callback A function building a p5.strands shader.
62121
+ * @param {Object} [scope] An optional scope object passed to .modify().
62085
62122
  * @returns {p5.Shader} The material shader.
62086
62123
  */
62087
62124
  /**
62088
62125
  * @method buildMaterialShader
62089
62126
  * @param {Object} hooks An object specifying p5.strands hooks in GLSL.
62127
+ * @param {Object} [scope] An optional scope object passed to .modify().
62090
62128
  * @returns {p5.Shader} The material shader.
62091
62129
  */
62092
- fn.buildMaterialShader = function (cb) {
62093
- return this.baseMaterialShader().modify(cb);
62130
+ fn.buildMaterialShader = function (cb, scope) {
62131
+ return this.baseMaterialShader().modify(cb, scope);
62094
62132
  };
62095
62133
 
62096
62134
  /**
@@ -62189,7 +62227,7 @@ var p5 = (function () {
62189
62227
  /**
62190
62228
  * Returns the base shader used for filters.
62191
62229
  *
62192
- * Calling <a href="#/p5/buildMaterialShader">`buildFilterShader(shaderFunction)`</a>
62230
+ * Calling <a href="#/p5/buildFilterShader">`buildFilterShader(shaderFunction)`</a>
62193
62231
  * is equivalent to calling `baseFilterShader().modify(shaderFunction)`.
62194
62232
  *
62195
62233
  * Read <a href="#/p5/buildFilterShader">the `buildFilterShader` reference</a> or
@@ -62298,15 +62336,17 @@ var p5 = (function () {
62298
62336
  * @submodule p5.strands
62299
62337
  * @beta
62300
62338
  * @param {Function} callback A function building a p5.strands shader.
62339
+ * @param {Object} [scope] An optional scope object passed to .modify().
62301
62340
  * @returns {p5.Shader} The normal shader.
62302
62341
  */
62303
62342
  /**
62304
62343
  * @method buildNormalShader
62305
62344
  * @param {Object} hooks An object specifying p5.strands hooks in GLSL.
62345
+ * @param {Object} [scope] An optional scope object passed to .modify().
62306
62346
  * @returns {p5.Shader} The normal shader.
62307
62347
  */
62308
- fn.buildNormalShader = function (cb) {
62309
- return this.baseNormalShader().modify(cb);
62348
+ fn.buildNormalShader = function (cb, scope) {
62349
+ return this.baseNormalShader().modify(cb, scope);
62310
62350
  };
62311
62351
 
62312
62352
  /**
@@ -62462,15 +62502,17 @@ var p5 = (function () {
62462
62502
  * @submodule p5.strands
62463
62503
  * @beta
62464
62504
  * @param {Function} callback A function building a p5.strands shader.
62505
+ * @param {Object} [scope] An optional scope object passed to .modify().
62465
62506
  * @returns {p5.Shader} The color shader.
62466
62507
  */
62467
62508
  /**
62468
62509
  * @method buildColorShader
62469
62510
  * @param {Object} hooks An object specifying p5.strands hooks in GLSL.
62511
+ * @param {Object} [scope] An optional scope object passed to .modify().
62470
62512
  * @returns {p5.Shader} The color shader.
62471
62513
  */
62472
- fn.buildColorShader = function (cb) {
62473
- return this.baseColorShader().modify(cb);
62514
+ fn.buildColorShader = function (cb, scope) {
62515
+ return this.baseColorShader().modify(cb, scope);
62474
62516
  };
62475
62517
 
62476
62518
  /**
@@ -62717,15 +62759,17 @@ var p5 = (function () {
62717
62759
  * @submodule p5.strands
62718
62760
  * @beta
62719
62761
  * @param {Function} callback A function building a p5.strands shader.
62762
+ * @param {Object} [scope] An optional scope object passed to .modify().
62720
62763
  * @returns {p5.Shader} The stroke shader.
62721
62764
  */
62722
62765
  /**
62723
62766
  * @method buildStrokeShader
62724
62767
  * @param {Object} hooks An object specifying p5.strands hooks in GLSL.
62768
+ * @param {Object} [scope] An optional scope object passed to .modify().
62725
62769
  * @returns {p5.Shader} The stroke shader.
62726
62770
  */
62727
- fn.buildStrokeShader = function (cb) {
62728
- return this.baseStrokeShader().modify(cb);
62771
+ fn.buildStrokeShader = function (cb, scope) {
62772
+ return this.baseStrokeShader().modify(cb, scope);
62729
62773
  };
62730
62774
 
62731
62775
  /**
@@ -69204,7 +69248,7 @@ var p5 = (function () {
69204
69248
  const baseType = orig?.baseType ?? BaseType.FLOAT;
69205
69249
 
69206
69250
  let newValueID;
69207
- if (value instanceof StrandsNode) {
69251
+ if (value?.isStrandsNode) {
69208
69252
  newValueID = value.id;
69209
69253
  } else {
69210
69254
  const newVal = primitiveConstructorNode(
@@ -69259,7 +69303,7 @@ var p5 = (function () {
69259
69303
  const baseType = orig?.baseType ?? BaseType.FLOAT;
69260
69304
 
69261
69305
  let newValueID;
69262
- if (value instanceof StrandsNode) {
69306
+ if (value?.isStrandsNode) {
69263
69307
  newValueID = value.id;
69264
69308
  } else {
69265
69309
  const newVal = primitiveConstructorNode(
@@ -69489,7 +69533,7 @@ var p5 = (function () {
69489
69533
  const { dag, cfg } = strandsContext;
69490
69534
  let dependsOn;
69491
69535
  let node;
69492
- if (nodeOrValue instanceof StrandsNode) {
69536
+ if (nodeOrValue?.isStrandsNode) {
69493
69537
  node = nodeOrValue;
69494
69538
  } else {
69495
69539
  const { id, dimension } = primitiveConstructorNode(strandsContext, { baseType: BaseType.FLOAT, dimension: null }, nodeOrValue);
@@ -69689,6 +69733,20 @@ var p5 = (function () {
69689
69733
 
69690
69734
  function primitiveConstructorNode(strandsContext, typeInfo, dependsOn) {
69691
69735
  const cfg = strandsContext.cfg;
69736
+ dependsOn = (Array.isArray(dependsOn) ? dependsOn : [dependsOn])
69737
+ .flat(Infinity)
69738
+ .map(a => {
69739
+ if (
69740
+ a.isStrandsNode &&
69741
+ a.typeInfo().baseType === BaseType.INT &&
69742
+ // TODO: handle ivec inputs instead of just int scalars
69743
+ a.typeInfo().dimension === 1
69744
+ ) {
69745
+ return castToFloat(strandsContext, a);
69746
+ } else {
69747
+ return a;
69748
+ }
69749
+ });
69692
69750
  const { mappedDependencies, inferredTypeInfo } = mapPrimitiveDepsToIDs(strandsContext, typeInfo, dependsOn);
69693
69751
 
69694
69752
  const finalType = {
@@ -69704,6 +69762,24 @@ var p5 = (function () {
69704
69762
  return { id, dimension: finalType.dimension, components: mappedDependencies };
69705
69763
  }
69706
69764
 
69765
+ function castToFloat(strandsContext, dep) {
69766
+ const { id, dimension } = functionCallNode(
69767
+ strandsContext,
69768
+ strandsContext.backend.getTypeName('float', dep.typeInfo().dimension),
69769
+ [dep],
69770
+ {
69771
+ overloads: [{
69772
+ params: [dep.typeInfo()],
69773
+ returnType: {
69774
+ ...dep.typeInfo(),
69775
+ baseType: BaseType.FLOAT,
69776
+ },
69777
+ }],
69778
+ }
69779
+ );
69780
+ return createStrandsNode(id, dimension, strandsContext);
69781
+ }
69782
+
69707
69783
  function structConstructorNode(strandsContext, structTypeInfo, rawUserArgs) {
69708
69784
  const { cfg, dag } = strandsContext;
69709
69785
  const { properties } = structTypeInfo;
@@ -69923,7 +69999,7 @@ var p5 = (function () {
69923
69999
  // This may not be the most efficient way, as we swizzle each component individually,
69924
70000
  // so that .xyz becomes .x, .y, .z
69925
70001
  let scalars = [];
69926
- if (value instanceof StrandsNode) {
70002
+ if (value?.isStrandsNode) {
69927
70003
  if (value.dimension === 1) {
69928
70004
  scalars = Array(chars.length).fill(value);
69929
70005
  } else if (value.dimension === chars.length) {
@@ -96589,7 +96665,7 @@ var p5 = (function () {
96589
96665
 
96590
96666
  try {
96591
96667
  const ast = parse(code, {
96592
- ecmaVersion: 2021,
96668
+ ecmaVersion: 'latest',
96593
96669
  sourceType: 'module',
96594
96670
  locations: true // This helps us get the line number.
96595
96671
  });
@@ -110022,12 +110098,10 @@ var p5 = (function () {
110022
110098
  const vertString = tokens[vertexTokens[tokenInd]];
110023
110099
  let vertParts = vertString.split('/');
110024
110100
 
110025
- // TODO: Faces can technically use negative numbers to refer to the
110026
- // previous nth vertex. I haven't seen this used in practice, but
110027
- // it might be good to implement this in the future.
110028
-
110029
110101
  for (let i = 0; i < vertParts.length; i++) {
110030
- vertParts[i] = parseInt(vertParts[i]) - 1;
110102
+ let index = parseInt(vertParts[i]);
110103
+ if (index > 0) index -= 1; // OBJ uses 1-based indexing
110104
+ vertParts[i] = index;
110031
110105
  }
110032
110106
 
110033
110107
  if (!usedVerts[vertString]) {
@@ -110036,11 +110110,11 @@ var p5 = (function () {
110036
110110
 
110037
110111
  if (usedVerts[vertString][currentMaterial] === undefined) {
110038
110112
  const vertIndex = model.vertices.length;
110039
- model.vertices.push(loadedVerts.v[vertParts[0]].copy());
110040
- model.uvs.push(loadedVerts.vt[vertParts[1]] ?
110041
- loadedVerts.vt[vertParts[1]].slice() : [0, 0]);
110042
- model.vertexNormals.push(loadedVerts.vn[vertParts[2]] ?
110043
- loadedVerts.vn[vertParts[2]].copy() : new Vector());
110113
+ model.vertices.push(loadedVerts.v.at(vertParts[0]).copy());
110114
+ model.uvs.push(loadedVerts.vt.at(vertParts[1]) ?
110115
+ loadedVerts.vt.at(vertParts[1]).slice() : [0, 0]);
110116
+ model.vertexNormals.push(loadedVerts.vn.at(vertParts[2]) ?
110117
+ loadedVerts.vn.at(vertParts[2]).copy() : new Vector());
110044
110118
 
110045
110119
  usedVerts[vertString][currentMaterial] = vertIndex;
110046
110120
  face.push(vertIndex);
@@ -120920,7 +120994,7 @@ var p5 = (function () {
120920
120994
 
120921
120995
  if (!p5.Font.hasGlyphData(this.states.textFont)) {
120922
120996
  console.log(
120923
- 'WEBGL: only Opentype (.otf) and Truetype (.ttf) fonts with glyph data are supported'
120997
+ 'WEBGL: only Opentype (.otf) and Truetype (.ttf) fonts with glyph data are supported. Make sure to set the font using textFont() before drawing text.'
120924
120998
  );
120925
120999
  return;
120926
121000
  }
@@ -132152,7 +132226,7 @@ var p5 = (function () {
132152
132226
  let initialVar = this.initialCb();
132153
132227
 
132154
132228
  // Convert to StrandsNode if it's not already one
132155
- if (!(initialVar instanceof StrandsNode)) {
132229
+ if (!(initialVar?.isStrandsNode)) {
132156
132230
  const { id, dimension } = primitiveConstructorNode(this.strandsContext, { baseType: BaseType.FLOAT, dimension: 1 }, initialVar);
132157
132231
  initialVar = createStrandsNode(id, dimension, this.strandsContext);
132158
132232
  }
@@ -132311,32 +132385,45 @@ var p5 = (function () {
132311
132385
  return strandsContext._builtinGlobals
132312
132386
  }
132313
132387
 
132314
- function getBuiltinGlobalNode(strandsContext, name) {
132315
- const spec = BUILTIN_GLOBAL_SPECS[name];
132316
- if (!spec) return null
132317
-
132388
+ function getOrCreateUniformNode(strandsContext, uniformName, typeInfo, defaultValueFn) {
132318
132389
  const cache = _getBuiltinGlobalsCache(strandsContext);
132319
- const uniformName = `_p5_global_${name}`;
132390
+
132320
132391
  const cached = cache.nodes.get(uniformName);
132321
- if (cached) return cached
132392
+ if (cached) return cached;
132322
132393
 
132323
132394
  if (!cache.uniformsAdded.has(uniformName)) {
132324
132395
  cache.uniformsAdded.add(uniformName);
132325
132396
  strandsContext.uniforms.push({
132326
132397
  name: uniformName,
132327
- typeInfo: spec.typeInfo,
132328
- defaultValue: () => {
132329
- const p5Instance = strandsContext.renderer?._pInst || strandsContext.p5?.instance;
132330
- return p5Instance ? spec.get(p5Instance) : undefined
132331
- },
132398
+ typeInfo,
132399
+ defaultValue: defaultValueFn,
132332
132400
  });
132333
132401
  }
132334
132402
 
132335
- const { id, dimension } = variableNode(strandsContext, spec.typeInfo, uniformName);
132403
+ const { id, dimension } = variableNode(strandsContext, typeInfo, uniformName);
132336
132404
  const node = createStrandsNode(id, dimension, strandsContext);
132337
- node._originalBuiltinName = name;
132338
132405
  cache.nodes.set(uniformName, node);
132339
- return node
132406
+ return node;
132407
+ }
132408
+
132409
+ function getBuiltinGlobalNode(strandsContext, name) {
132410
+ const spec = BUILTIN_GLOBAL_SPECS[name];
132411
+ if (!spec) return null;
132412
+
132413
+ const uniformName = `_p5_global_${name}`;
132414
+ const instance = strandsContext.renderer?._pInst || strandsContext.p5?.instance;
132415
+
132416
+ const node = getOrCreateUniformNode(
132417
+ strandsContext,
132418
+ uniformName,
132419
+ spec.typeInfo,
132420
+ () => {
132421
+ return instance ? spec.get(instance) : undefined;
132422
+ }
132423
+ );
132424
+
132425
+ node._originalBuiltinName = name;
132426
+ return node;
132340
132427
  }
132341
132428
 
132342
132429
  function installBuiltinGlobalAccessors(strandsContext) {
@@ -132412,7 +132499,7 @@ var p5 = (function () {
132412
132499
  }
132413
132500
 
132414
132501
  // Convert value to a StrandsNode if it isn't already
132415
- const valueNode = value instanceof StrandsNode ? value : p5.strandsNode(value);
132502
+ const valueNode = value?.isStrandsNode ? value : p5.strandsNode(value);
132416
132503
 
132417
132504
  // Create a new CFG block for the early return
132418
132505
  const earlyReturnBlockID = createBasicBlock(cfg, BlockType.DEFAULT);
@@ -132499,6 +132586,7 @@ var p5 = (function () {
132499
132586
  // Add noise function with backend-agnostic implementation
132500
132587
  const originalNoise = fn.noise;
132501
132588
  const originalNoiseDetail = fn.noiseDetail;
132589
+ const originalMillis = fn.millis;
132502
132590
 
132503
132591
  strandsContext._noiseOctaves = null;
132504
132592
  strandsContext._noiseAmpFalloff = null;
@@ -132561,6 +132649,21 @@ var p5 = (function () {
132561
132649
  return createStrandsNode(id, dimension, strandsContext);
132562
132650
  };
132563
132651
 
132652
+ fn.millis = function (...args) {
132653
+ if (!strandsContext.active) {
132654
+ return originalMillis.apply(this, args);
132655
+ }
132656
+ const instance = strandsContext.renderer?._pInst || strandsContext.p5?.instance;
132657
+ return getOrCreateUniformNode(
132658
+ strandsContext,
132659
+ '_p5_global_millis',
132660
+ DataType.float1,
132661
+ () => {
132662
+ return instance ? instance.millis() : undefined;
132663
+ }
132664
+ );
132665
+ };
132666
+
132564
132667
  // Next is type constructors and uniform functions.
132565
132668
  // For some of them, we have aliases so that you can write either a more human-readable
132566
132669
  // variant or also one more directly translated from GLSL, or to be more compatible with
@@ -132627,12 +132730,17 @@ var p5 = (function () {
132627
132730
  fn[typeInfo.fnName] = function(...args) {
132628
132731
  if (strandsContext.active) {
132629
132732
  if (args.length === 1 && args[0].dimension && args[0].dimension === typeInfo.dimension) {
132630
- const { id, dimension } = functionCallNode(strandsContext, typeInfo.fnName, args, {
132631
- overloads: [{
132632
- params: [args[0].typeInfo()],
132633
- returnType: typeInfo,
132634
- }]
132635
- });
132733
+ const { id, dimension } = functionCallNode(
132734
+ strandsContext,
132735
+ strandsContext.backend.getTypeName(typeInfo.baseType, typeInfo.dimension),
132736
+ args,
132737
+ {
132738
+ overloads: [{
132739
+ params: [args[0].typeInfo()],
132740
+ returnType: typeInfo,
132741
+ }]
132742
+ }
132743
+ );
132636
132744
  return createStrandsNode(id, dimension, strandsContext);
132637
132745
  } else {
132638
132746
  // For vector types with a single argument, repeat it for each component
@@ -132689,7 +132797,7 @@ var p5 = (function () {
132689
132797
  const oldDependsOn = dag.dependsOn[structNode.id];
132690
132798
  const newDependsOn = [...oldDependsOn];
132691
132799
  let newValueID;
132692
- if (val instanceof StrandsNode) {
132800
+ if (val?.isStrandsNode) {
132693
132801
  newValueID = val.id;
132694
132802
  }
132695
132803
  else {
@@ -132721,7 +132829,7 @@ var p5 = (function () {
132721
132829
  return args;
132722
132830
  }
132723
132831
  function enforceReturnTypeMatch(strandsContext, expectedType, returned, hookName) {
132724
- if (!(returned instanceof StrandsNode)) {
132832
+ if (!(returned?.isStrandsNode)) {
132725
132833
  // try {
132726
132834
  const result = primitiveConstructorNode(strandsContext, expectedType, returned);
132727
132835
  return result.id;
@@ -132743,7 +132851,12 @@ var p5 = (function () {
132743
132851
  };
132744
132852
  if (receivedType.dimension !== expectedType.dimension) {
132745
132853
  if (receivedType.dimension !== 1) {
132746
- userError('type error', `You have returned a vector with ${receivedType.dimension} components in ${hookName} when a ${expectedType.baseType + expectedType.dimension} was expected!`);
132854
+ const receivedTypeDisplay = receivedType.baseType + (receivedType.dimension > 1 ? receivedType.dimension : '');
132855
+ const expectedTypeDisplay = expectedType.baseType + expectedType.dimension;
132856
+ userError('type error',
132857
+ `You have returned a ${receivedTypeDisplay} in ${hookName} when a ${expectedTypeDisplay} was expected!\n\n` +
132858
+ `Make sure your hook returns the correct type.`
132859
+ );
132747
132860
  }
132748
132861
  else {
132749
132862
  const result = primitiveConstructorNode(strandsContext, expectedType, returned);
@@ -132830,10 +132943,27 @@ var p5 = (function () {
132830
132943
  const handleRetVal = (retNode) => {
132831
132944
  if(isStructType(expectedReturnType)) {
132832
132945
  const expectedStructType = structType(expectedReturnType);
132833
- if (retNode instanceof StrandsNode) {
132946
+ if (retNode?.isStrandsNode) {
132834
132947
  const returnedNode = getNodeDataFromID(strandsContext.dag, retNode.id);
132835
132948
  if (returnedNode.baseType !== expectedStructType.typeName) {
132836
- userError("type error", `You have returned a ${retNode.baseType} from ${hookType.name} when a ${expectedStructType.typeName} was expected.`);
132949
+ const receivedTypeName = returnedNode.baseType || 'undefined';
132950
+ const receivedDim = dag.dimensions[retNode.id];
132951
+ const receivedTypeDisplay = receivedDim > 1 ?
132952
+ `${receivedTypeName}${receivedDim}` : receivedTypeName;
132953
+
132954
+ const expectedProps = expectedStructType.properties
132955
+ .map(p => p.name).join(', ');
132956
+ userError('type error',
132957
+ `You have returned a ${receivedTypeDisplay} from ${hookType.name} when a ${expectedStructType.typeName} was expected.\n\n` +
132958
+ `The ${expectedStructType.typeName} struct has these properties: { ${expectedProps} }\n\n` +
132959
+ `Instead of returning a different type, you should modify and return the ${expectedStructType.typeName} struct that was passed to your hook.\n\n` +
132960
+ `For example:\n` +
132961
+ `${hookType.name}((inputs) => {\n` +
132962
+ ` // Modify properties of inputs\n` +
132963
+ ` inputs.someProperty = ...;\n` +
132964
+ ` return inputs; // Return the modified struct\n` +
132965
+ `})`
132966
+ );
132837
132967
  }
132838
132968
  const newDeps = returnedNode.dependsOn.slice();
132839
132969
  for (let i = 0; i < expectedStructType.properties.length; i++) {
@@ -132852,10 +132982,14 @@ var p5 = (function () {
132852
132982
  const propName = expectedProp.name;
132853
132983
  const receivedValue = retNode[propName];
132854
132984
  if (receivedValue === undefined) {
132855
- userError('type error', `You've returned an incomplete struct from ${hookType.name}.\n` +
132856
- `Expected: { ${expectedReturnType.properties.map(p => p.name).join(', ')} }\n` +
132857
- `Received: { ${Object.keys(retNode).join(', ')} }\n` +
132858
- `All of the properties are required!`);
132985
+ const expectedProps = expectedReturnType.properties.map(p => p.name).join(', ');
132986
+ const receivedProps = Object.keys(retNode).join(', ');
132987
+ userError('type error',
132988
+ `You've returned an incomplete ${expectedStructType.typeName} struct from ${hookType.name}.\n\n` +
132989
+ `Expected properties: { ${expectedProps} }\n` +
132990
+ `Received properties: { ${receivedProps} }\n\n` +
132991
+ `All properties are required! Make sure to include all properties in the returned struct.`
132992
+ );
132859
132993
  }
132860
132994
  const expectedTypeInfo = expectedProp.dataType;
132861
132995
  const returnedPropID = enforceReturnTypeMatch(strandsContext, expectedTypeInfo, receivedValue, hookType.name);