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.
- package/dist/accessibility/color_namer.js +5 -5
- package/dist/accessibility/index.js +5 -5
- package/dist/app.js +5 -5
- package/dist/color/color_conversion.js +5 -5
- package/dist/color/index.js +1 -1
- package/dist/color/setting.js +1 -1
- package/dist/{constants-DQyACdzq.js → constants-D3npMLOW.js} +1 -1
- package/dist/core/constants.js +1 -1
- package/dist/core/environment.js +1 -1
- package/dist/core/filterShaders.js +1 -1
- package/dist/core/friendly_errors/fes_core.js +1 -1
- package/dist/core/friendly_errors/file_errors.js +1 -1
- package/dist/core/friendly_errors/index.js +1 -1
- package/dist/core/friendly_errors/param_validator.js +1 -1
- package/dist/core/friendly_errors/sketch_verifier.js +2 -2
- package/dist/core/helpers.js +1 -1
- package/dist/core/init.js +5 -5
- package/dist/core/internationalization.js +1 -1
- package/dist/core/legacy.js +5 -5
- package/dist/core/main.js +5 -5
- package/dist/core/p5.Graphics.js +3 -3
- package/dist/core/p5.Renderer.js +2 -2
- package/dist/core/p5.Renderer2D.js +5 -5
- package/dist/core/p5.Renderer3D.js +3 -3
- package/dist/core/rendering.js +3 -3
- package/dist/dom/dom.js +1 -1
- package/dist/dom/index.js +1 -1
- package/dist/dom/p5.Element.js +1 -1
- package/dist/dom/p5.MediaElement.js +1 -1
- package/dist/image/const.js +1 -1
- package/dist/image/filterRenderer2D.js +4 -4
- package/dist/image/image.js +3 -3
- package/dist/image/index.js +3 -3
- package/dist/image/loading_displaying.js +3 -3
- package/dist/image/p5.Image.js +2 -2
- package/dist/io/files.js +3 -3
- package/dist/io/index.js +3 -3
- package/dist/{ir_builders-DXNgaB9N.js → ir_builders-w12-GSxu.js} +37 -5
- package/dist/{main-DvN69W3f.js → main-C5AeICIY.js} +3 -3
- package/dist/math/Matrices/Matrix.js +1 -1
- package/dist/math/Matrices/MatrixNumjs.js +1 -1
- package/dist/math/index.js +1 -1
- package/dist/math/p5.Matrix.js +1 -1
- package/dist/math/p5.Vector.js +1 -1
- package/dist/math/trigonometry.js +1 -1
- package/dist/{p5.Renderer-D-5LdCRz.js → p5.Renderer-xpFkUQC6.js} +1 -1
- package/dist/{rendering-h9unX5K0.js → rendering-B8po3Onj.js} +57 -13
- package/dist/shape/2d_primitives.js +1 -1
- package/dist/shape/attributes.js +1 -1
- package/dist/shape/custom_shapes.js +1 -1
- package/dist/shape/index.js +1 -1
- package/dist/strands/ir_builders.js +1 -1
- package/dist/strands/p5.strands.js +1 -1
- package/dist/strands/strands_api.js +49 -18
- package/dist/strands/strands_conditionals.js +1 -1
- package/dist/strands/strands_for.js +2 -2
- package/dist/strands/strands_node.js +1 -1
- package/dist/type/index.js +2 -2
- package/dist/type/p5.Font.js +2 -2
- package/dist/type/textCore.js +2 -2
- package/dist/webgl/3d_primitives.js +3 -3
- package/dist/webgl/GeometryBuilder.js +1 -1
- package/dist/webgl/ShapeBuilder.js +1 -1
- package/dist/webgl/enums.js +1 -1
- package/dist/webgl/index.js +4 -4
- package/dist/webgl/interaction.js +1 -1
- package/dist/webgl/light.js +3 -3
- package/dist/webgl/loading.js +11 -13
- package/dist/webgl/material.js +3 -3
- package/dist/webgl/p5.Camera.js +3 -3
- package/dist/webgl/p5.Framebuffer.js +3 -3
- package/dist/webgl/p5.Geometry.js +1 -1
- package/dist/webgl/p5.Quat.js +1 -1
- package/dist/webgl/p5.RendererGL.js +4 -4
- package/dist/webgl/p5.Texture.js +3 -3
- package/dist/webgl/strands_glslBackend.js +1 -1
- package/dist/webgl/text.js +4 -4
- package/dist/webgl/utils.js +3 -3
- package/dist/webgpu/index.js +2 -2
- package/dist/webgpu/p5.RendererWebGPU.js +13 -4
- package/dist/webgpu/strands_wgslBackend.js +5 -4
- package/lib/p5.esm.js +152 -47
- package/lib/p5.esm.min.js +1 -1
- package/lib/p5.js +152 -47
- package/lib/p5.min.js +1 -1
- package/lib/p5.webgpu.esm.js +51 -9
- package/lib/p5.webgpu.js +51 -9
- package/lib/p5.webgpu.min.js +1 -1
- package/package.json +1 -1
- package/types/global.d.ts +1449 -1379
- package/types/p5.d.ts +727 -692
package/lib/p5.esm.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! p5.js v2.2.
|
|
1
|
+
/*! p5.js v2.2.2-rc.0 February 18, 2026 */
|
|
2
2
|
/**
|
|
3
3
|
* @module Constants
|
|
4
4
|
* @submodule Constants
|
|
@@ -12,7 +12,7 @@ const _PI = Math.PI;
|
|
|
12
12
|
* @property {String} VERSION
|
|
13
13
|
* @final
|
|
14
14
|
*/
|
|
15
|
-
const VERSION = '2.2.
|
|
15
|
+
const VERSION = '2.2.2-rc.0';
|
|
16
16
|
|
|
17
17
|
// GRAPHICS RENDERER
|
|
18
18
|
/**
|
|
@@ -61237,6 +61237,40 @@ function material(p5, fn) {
|
|
|
61237
61237
|
* }
|
|
61238
61238
|
* ```
|
|
61239
61239
|
*
|
|
61240
|
+
* 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.
|
|
61241
|
+
*
|
|
61242
|
+
* ```js example
|
|
61243
|
+
* let myFilter;
|
|
61244
|
+
*
|
|
61245
|
+
* function setup() {
|
|
61246
|
+
* createCanvas(100, 100, WEBGL);
|
|
61247
|
+
* myFilter = buildFilterShader(noiseShaderCallback);
|
|
61248
|
+
* describe('Evolving animated cloud-like noise in cyan and magenta');
|
|
61249
|
+
* }
|
|
61250
|
+
*
|
|
61251
|
+
* function noiseShaderCallback() {
|
|
61252
|
+
* let time = uniformFloat();
|
|
61253
|
+
* filterColor.begin();
|
|
61254
|
+
* let coord = filterColor.texCoord;
|
|
61255
|
+
*
|
|
61256
|
+
* //generate a value roughly between 0 and 1
|
|
61257
|
+
* let noiseVal = noise(coord.x, coord.y, time / 2000);
|
|
61258
|
+
*
|
|
61259
|
+
* let result = mix(
|
|
61260
|
+
* [1, 0, 1, 1], // Magenta
|
|
61261
|
+
* [0, 1, 1, 1], // Cyan
|
|
61262
|
+
* noiseVal
|
|
61263
|
+
* );
|
|
61264
|
+
* filterColor.set(result);
|
|
61265
|
+
* filterColor.end();
|
|
61266
|
+
* }
|
|
61267
|
+
*
|
|
61268
|
+
* function draw() {
|
|
61269
|
+
* myFilter.setUniform("time", millis());
|
|
61270
|
+
* filter(myFilter);
|
|
61271
|
+
* }
|
|
61272
|
+
* ```
|
|
61273
|
+
*
|
|
61240
61274
|
* Like the `modify()` method on shaders,
|
|
61241
61275
|
* 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>
|
|
61242
61276
|
* instead of JavaScript.
|
|
@@ -61251,15 +61285,17 @@ function material(p5, fn) {
|
|
|
61251
61285
|
* @beta
|
|
61252
61286
|
* @submodule p5.strands
|
|
61253
61287
|
* @param {Function} callback A function building a p5.strands shader.
|
|
61288
|
+
* @param {Object} [scope] An optional scope object passed to .modify().
|
|
61254
61289
|
* @returns {p5.Shader} The material shader
|
|
61255
61290
|
*/
|
|
61256
61291
|
/**
|
|
61257
61292
|
* @method buildFilterShader
|
|
61258
61293
|
* @param {Object} hooks An object specifying p5.strands hooks in GLSL.
|
|
61294
|
+
* @param {Object} [scope] An optional scope object passed to .modify().
|
|
61259
61295
|
* @returns {p5.Shader} The material shader
|
|
61260
61296
|
*/
|
|
61261
|
-
fn.buildFilterShader = function (callback) {
|
|
61262
|
-
return this.baseFilterShader().modify(callback);
|
|
61297
|
+
fn.buildFilterShader = function (callback, scope) {
|
|
61298
|
+
return this.baseFilterShader().modify(callback, scope);
|
|
61263
61299
|
};
|
|
61264
61300
|
|
|
61265
61301
|
/**
|
|
@@ -62079,15 +62115,17 @@ function material(p5, fn) {
|
|
|
62079
62115
|
* @submodule p5.strands
|
|
62080
62116
|
* @beta
|
|
62081
62117
|
* @param {Function} callback A function building a p5.strands shader.
|
|
62118
|
+
* @param {Object} [scope] An optional scope object passed to .modify().
|
|
62082
62119
|
* @returns {p5.Shader} The material shader.
|
|
62083
62120
|
*/
|
|
62084
62121
|
/**
|
|
62085
62122
|
* @method buildMaterialShader
|
|
62086
62123
|
* @param {Object} hooks An object specifying p5.strands hooks in GLSL.
|
|
62124
|
+
* @param {Object} [scope] An optional scope object passed to .modify().
|
|
62087
62125
|
* @returns {p5.Shader} The material shader.
|
|
62088
62126
|
*/
|
|
62089
|
-
fn.buildMaterialShader = function (cb) {
|
|
62090
|
-
return this.baseMaterialShader().modify(cb);
|
|
62127
|
+
fn.buildMaterialShader = function (cb, scope) {
|
|
62128
|
+
return this.baseMaterialShader().modify(cb, scope);
|
|
62091
62129
|
};
|
|
62092
62130
|
|
|
62093
62131
|
/**
|
|
@@ -62186,7 +62224,7 @@ function material(p5, fn) {
|
|
|
62186
62224
|
/**
|
|
62187
62225
|
* Returns the base shader used for filters.
|
|
62188
62226
|
*
|
|
62189
|
-
* Calling <a href="#/p5/
|
|
62227
|
+
* Calling <a href="#/p5/buildFilterShader">`buildFilterShader(shaderFunction)`</a>
|
|
62190
62228
|
* is equivalent to calling `baseFilterShader().modify(shaderFunction)`.
|
|
62191
62229
|
*
|
|
62192
62230
|
* Read <a href="#/p5/buildFilterShader">the `buildFilterShader` reference</a> or
|
|
@@ -62295,15 +62333,17 @@ function material(p5, fn) {
|
|
|
62295
62333
|
* @submodule p5.strands
|
|
62296
62334
|
* @beta
|
|
62297
62335
|
* @param {Function} callback A function building a p5.strands shader.
|
|
62336
|
+
* @param {Object} [scope] An optional scope object passed to .modify().
|
|
62298
62337
|
* @returns {p5.Shader} The normal shader.
|
|
62299
62338
|
*/
|
|
62300
62339
|
/**
|
|
62301
62340
|
* @method buildNormalShader
|
|
62302
62341
|
* @param {Object} hooks An object specifying p5.strands hooks in GLSL.
|
|
62342
|
+
* @param {Object} [scope] An optional scope object passed to .modify().
|
|
62303
62343
|
* @returns {p5.Shader} The normal shader.
|
|
62304
62344
|
*/
|
|
62305
|
-
fn.buildNormalShader = function (cb) {
|
|
62306
|
-
return this.baseNormalShader().modify(cb);
|
|
62345
|
+
fn.buildNormalShader = function (cb, scope) {
|
|
62346
|
+
return this.baseNormalShader().modify(cb, scope);
|
|
62307
62347
|
};
|
|
62308
62348
|
|
|
62309
62349
|
/**
|
|
@@ -62459,15 +62499,17 @@ function material(p5, fn) {
|
|
|
62459
62499
|
* @submodule p5.strands
|
|
62460
62500
|
* @beta
|
|
62461
62501
|
* @param {Function} callback A function building a p5.strands shader.
|
|
62502
|
+
* @param {Object} [scope] An optional scope object passed to .modify().
|
|
62462
62503
|
* @returns {p5.Shader} The color shader.
|
|
62463
62504
|
*/
|
|
62464
62505
|
/**
|
|
62465
62506
|
* @method buildColorShader
|
|
62466
62507
|
* @param {Object} hooks An object specifying p5.strands hooks in GLSL.
|
|
62508
|
+
* @param {Object} [scope] An optional scope object passed to .modify().
|
|
62467
62509
|
* @returns {p5.Shader} The color shader.
|
|
62468
62510
|
*/
|
|
62469
|
-
fn.buildColorShader = function (cb) {
|
|
62470
|
-
return this.baseColorShader().modify(cb);
|
|
62511
|
+
fn.buildColorShader = function (cb, scope) {
|
|
62512
|
+
return this.baseColorShader().modify(cb, scope);
|
|
62471
62513
|
};
|
|
62472
62514
|
|
|
62473
62515
|
/**
|
|
@@ -62714,15 +62756,17 @@ function material(p5, fn) {
|
|
|
62714
62756
|
* @submodule p5.strands
|
|
62715
62757
|
* @beta
|
|
62716
62758
|
* @param {Function} callback A function building a p5.strands shader.
|
|
62759
|
+
* @param {Object} [scope] An optional scope object passed to .modify().
|
|
62717
62760
|
* @returns {p5.Shader} The stroke shader.
|
|
62718
62761
|
*/
|
|
62719
62762
|
/**
|
|
62720
62763
|
* @method buildStrokeShader
|
|
62721
62764
|
* @param {Object} hooks An object specifying p5.strands hooks in GLSL.
|
|
62765
|
+
* @param {Object} [scope] An optional scope object passed to .modify().
|
|
62722
62766
|
* @returns {p5.Shader} The stroke shader.
|
|
62723
62767
|
*/
|
|
62724
|
-
fn.buildStrokeShader = function (cb) {
|
|
62725
|
-
return this.baseStrokeShader().modify(cb);
|
|
62768
|
+
fn.buildStrokeShader = function (cb, scope) {
|
|
62769
|
+
return this.baseStrokeShader().modify(cb, scope);
|
|
62726
62770
|
};
|
|
62727
62771
|
|
|
62728
62772
|
/**
|
|
@@ -69201,7 +69245,7 @@ class StrandsNode {
|
|
|
69201
69245
|
const baseType = orig?.baseType ?? BaseType.FLOAT;
|
|
69202
69246
|
|
|
69203
69247
|
let newValueID;
|
|
69204
|
-
if (value
|
|
69248
|
+
if (value?.isStrandsNode) {
|
|
69205
69249
|
newValueID = value.id;
|
|
69206
69250
|
} else {
|
|
69207
69251
|
const newVal = primitiveConstructorNode(
|
|
@@ -69256,7 +69300,7 @@ class StrandsNode {
|
|
|
69256
69300
|
const baseType = orig?.baseType ?? BaseType.FLOAT;
|
|
69257
69301
|
|
|
69258
69302
|
let newValueID;
|
|
69259
|
-
if (value
|
|
69303
|
+
if (value?.isStrandsNode) {
|
|
69260
69304
|
newValueID = value.id;
|
|
69261
69305
|
} else {
|
|
69262
69306
|
const newVal = primitiveConstructorNode(
|
|
@@ -69486,7 +69530,7 @@ function unaryOpNode(strandsContext, nodeOrValue, opCode) {
|
|
|
69486
69530
|
const { dag, cfg } = strandsContext;
|
|
69487
69531
|
let dependsOn;
|
|
69488
69532
|
let node;
|
|
69489
|
-
if (nodeOrValue
|
|
69533
|
+
if (nodeOrValue?.isStrandsNode) {
|
|
69490
69534
|
node = nodeOrValue;
|
|
69491
69535
|
} else {
|
|
69492
69536
|
const { id, dimension } = primitiveConstructorNode(strandsContext, { baseType: BaseType.FLOAT, dimension: null }, nodeOrValue);
|
|
@@ -69686,6 +69730,20 @@ function constructTypeFromIDs(strandsContext, typeInfo, strandsNodesArray) {
|
|
|
69686
69730
|
|
|
69687
69731
|
function primitiveConstructorNode(strandsContext, typeInfo, dependsOn) {
|
|
69688
69732
|
const cfg = strandsContext.cfg;
|
|
69733
|
+
dependsOn = (Array.isArray(dependsOn) ? dependsOn : [dependsOn])
|
|
69734
|
+
.flat(Infinity)
|
|
69735
|
+
.map(a => {
|
|
69736
|
+
if (
|
|
69737
|
+
a.isStrandsNode &&
|
|
69738
|
+
a.typeInfo().baseType === BaseType.INT &&
|
|
69739
|
+
// TODO: handle ivec inputs instead of just int scalars
|
|
69740
|
+
a.typeInfo().dimension === 1
|
|
69741
|
+
) {
|
|
69742
|
+
return castToFloat(strandsContext, a);
|
|
69743
|
+
} else {
|
|
69744
|
+
return a;
|
|
69745
|
+
}
|
|
69746
|
+
});
|
|
69689
69747
|
const { mappedDependencies, inferredTypeInfo } = mapPrimitiveDepsToIDs(strandsContext, typeInfo, dependsOn);
|
|
69690
69748
|
|
|
69691
69749
|
const finalType = {
|
|
@@ -69701,6 +69759,24 @@ function primitiveConstructorNode(strandsContext, typeInfo, dependsOn) {
|
|
|
69701
69759
|
return { id, dimension: finalType.dimension, components: mappedDependencies };
|
|
69702
69760
|
}
|
|
69703
69761
|
|
|
69762
|
+
function castToFloat(strandsContext, dep) {
|
|
69763
|
+
const { id, dimension } = functionCallNode(
|
|
69764
|
+
strandsContext,
|
|
69765
|
+
strandsContext.backend.getTypeName('float', dep.typeInfo().dimension),
|
|
69766
|
+
[dep],
|
|
69767
|
+
{
|
|
69768
|
+
overloads: [{
|
|
69769
|
+
params: [dep.typeInfo()],
|
|
69770
|
+
returnType: {
|
|
69771
|
+
...dep.typeInfo(),
|
|
69772
|
+
baseType: BaseType.FLOAT,
|
|
69773
|
+
},
|
|
69774
|
+
}],
|
|
69775
|
+
}
|
|
69776
|
+
);
|
|
69777
|
+
return createStrandsNode(id, dimension, strandsContext);
|
|
69778
|
+
}
|
|
69779
|
+
|
|
69704
69780
|
function structConstructorNode(strandsContext, structTypeInfo, rawUserArgs) {
|
|
69705
69781
|
const { cfg, dag } = strandsContext;
|
|
69706
69782
|
const { properties } = structTypeInfo;
|
|
@@ -69920,7 +69996,7 @@ function swizzleTrap(id, dimension, strandsContext, onRebind) {
|
|
|
69920
69996
|
// This may not be the most efficient way, as we swizzle each component individually,
|
|
69921
69997
|
// so that .xyz becomes .x, .y, .z
|
|
69922
69998
|
let scalars = [];
|
|
69923
|
-
if (value
|
|
69999
|
+
if (value?.isStrandsNode) {
|
|
69924
70000
|
if (value.dimension === 1) {
|
|
69925
70001
|
scalars = Array(chars.length).fill(value);
|
|
69926
70002
|
} else if (value.dimension === chars.length) {
|
|
@@ -96586,7 +96662,7 @@ const verifierUtils = {
|
|
|
96586
96662
|
|
|
96587
96663
|
try {
|
|
96588
96664
|
const ast = parse(code, {
|
|
96589
|
-
ecmaVersion:
|
|
96665
|
+
ecmaVersion: 'latest',
|
|
96590
96666
|
sourceType: 'module',
|
|
96591
96667
|
locations: true // This helps us get the line number.
|
|
96592
96668
|
});
|
|
@@ -110019,12 +110095,10 @@ function loading$1(p5, fn){
|
|
|
110019
110095
|
const vertString = tokens[vertexTokens[tokenInd]];
|
|
110020
110096
|
let vertParts = vertString.split('/');
|
|
110021
110097
|
|
|
110022
|
-
// TODO: Faces can technically use negative numbers to refer to the
|
|
110023
|
-
// previous nth vertex. I haven't seen this used in practice, but
|
|
110024
|
-
// it might be good to implement this in the future.
|
|
110025
|
-
|
|
110026
110098
|
for (let i = 0; i < vertParts.length; i++) {
|
|
110027
|
-
|
|
110099
|
+
let index = parseInt(vertParts[i]);
|
|
110100
|
+
if (index > 0) index -= 1; // OBJ uses 1-based indexing
|
|
110101
|
+
vertParts[i] = index;
|
|
110028
110102
|
}
|
|
110029
110103
|
|
|
110030
110104
|
if (!usedVerts[vertString]) {
|
|
@@ -110033,11 +110107,11 @@ function loading$1(p5, fn){
|
|
|
110033
110107
|
|
|
110034
110108
|
if (usedVerts[vertString][currentMaterial] === undefined) {
|
|
110035
110109
|
const vertIndex = model.vertices.length;
|
|
110036
|
-
model.vertices.push(loadedVerts.v
|
|
110037
|
-
model.uvs.push(loadedVerts.vt
|
|
110038
|
-
loadedVerts.vt
|
|
110039
|
-
model.vertexNormals.push(loadedVerts.vn
|
|
110040
|
-
loadedVerts.vn
|
|
110110
|
+
model.vertices.push(loadedVerts.v.at(vertParts[0]).copy());
|
|
110111
|
+
model.uvs.push(loadedVerts.vt.at(vertParts[1]) ?
|
|
110112
|
+
loadedVerts.vt.at(vertParts[1]).slice() : [0, 0]);
|
|
110113
|
+
model.vertexNormals.push(loadedVerts.vn.at(vertParts[2]) ?
|
|
110114
|
+
loadedVerts.vn.at(vertParts[2]).copy() : new Vector());
|
|
110041
110115
|
|
|
110042
110116
|
usedVerts[vertString][currentMaterial] = vertIndex;
|
|
110043
110117
|
face.push(vertIndex);
|
|
@@ -120917,7 +120991,7 @@ function text(p5, fn) {
|
|
|
120917
120991
|
|
|
120918
120992
|
if (!p5.Font.hasGlyphData(this.states.textFont)) {
|
|
120919
120993
|
console.log(
|
|
120920
|
-
'WEBGL: only Opentype (.otf) and Truetype (.ttf) fonts with glyph data are supported'
|
|
120994
|
+
'WEBGL: only Opentype (.otf) and Truetype (.ttf) fonts with glyph data are supported. Make sure to set the font using textFont() before drawing text.'
|
|
120921
120995
|
);
|
|
120922
120996
|
return;
|
|
120923
120997
|
}
|
|
@@ -132149,7 +132223,7 @@ class StrandsFor {
|
|
|
132149
132223
|
let initialVar = this.initialCb();
|
|
132150
132224
|
|
|
132151
132225
|
// Convert to StrandsNode if it's not already one
|
|
132152
|
-
if (!(initialVar
|
|
132226
|
+
if (!(initialVar?.isStrandsNode)) {
|
|
132153
132227
|
const { id, dimension } = primitiveConstructorNode(this.strandsContext, { baseType: BaseType.FLOAT, dimension: 1 }, initialVar);
|
|
132154
132228
|
initialVar = createStrandsNode(id, dimension, this.strandsContext);
|
|
132155
132229
|
}
|
|
@@ -132311,7 +132385,7 @@ function _getBuiltinGlobalsCache(strandsContext) {
|
|
|
132311
132385
|
function getBuiltinGlobalNode(strandsContext, name) {
|
|
132312
132386
|
const spec = BUILTIN_GLOBAL_SPECS[name];
|
|
132313
132387
|
if (!spec) return null
|
|
132314
|
-
|
|
132388
|
+
|
|
132315
132389
|
const cache = _getBuiltinGlobalsCache(strandsContext);
|
|
132316
132390
|
const uniformName = `_p5_global_${name}`;
|
|
132317
132391
|
const cached = cache.nodes.get(uniformName);
|
|
@@ -132409,7 +132483,7 @@ function initGlobalStrandsAPI(p5, fn, strandsContext) {
|
|
|
132409
132483
|
}
|
|
132410
132484
|
|
|
132411
132485
|
// Convert value to a StrandsNode if it isn't already
|
|
132412
|
-
const valueNode = value
|
|
132486
|
+
const valueNode = value?.isStrandsNode ? value : p5.strandsNode(value);
|
|
132413
132487
|
|
|
132414
132488
|
// Create a new CFG block for the early return
|
|
132415
132489
|
const earlyReturnBlockID = createBasicBlock(cfg, BlockType.DEFAULT);
|
|
@@ -132624,12 +132698,17 @@ function initGlobalStrandsAPI(p5, fn, strandsContext) {
|
|
|
132624
132698
|
fn[typeInfo.fnName] = function(...args) {
|
|
132625
132699
|
if (strandsContext.active) {
|
|
132626
132700
|
if (args.length === 1 && args[0].dimension && args[0].dimension === typeInfo.dimension) {
|
|
132627
|
-
const { id, dimension } = functionCallNode(
|
|
132628
|
-
|
|
132629
|
-
|
|
132630
|
-
|
|
132631
|
-
|
|
132632
|
-
|
|
132701
|
+
const { id, dimension } = functionCallNode(
|
|
132702
|
+
strandsContext,
|
|
132703
|
+
strandsContext.backend.getTypeName(typeInfo.baseType, typeInfo.dimension),
|
|
132704
|
+
args,
|
|
132705
|
+
{
|
|
132706
|
+
overloads: [{
|
|
132707
|
+
params: [args[0].typeInfo()],
|
|
132708
|
+
returnType: typeInfo,
|
|
132709
|
+
}]
|
|
132710
|
+
}
|
|
132711
|
+
);
|
|
132633
132712
|
return createStrandsNode(id, dimension, strandsContext);
|
|
132634
132713
|
} else {
|
|
132635
132714
|
// For vector types with a single argument, repeat it for each component
|
|
@@ -132686,7 +132765,7 @@ function createHookArguments(strandsContext, parameters){
|
|
|
132686
132765
|
const oldDependsOn = dag.dependsOn[structNode.id];
|
|
132687
132766
|
const newDependsOn = [...oldDependsOn];
|
|
132688
132767
|
let newValueID;
|
|
132689
|
-
if (val
|
|
132768
|
+
if (val?.isStrandsNode) {
|
|
132690
132769
|
newValueID = val.id;
|
|
132691
132770
|
}
|
|
132692
132771
|
else {
|
|
@@ -132718,7 +132797,7 @@ function createHookArguments(strandsContext, parameters){
|
|
|
132718
132797
|
return args;
|
|
132719
132798
|
}
|
|
132720
132799
|
function enforceReturnTypeMatch(strandsContext, expectedType, returned, hookName) {
|
|
132721
|
-
if (!(returned
|
|
132800
|
+
if (!(returned?.isStrandsNode)) {
|
|
132722
132801
|
// try {
|
|
132723
132802
|
const result = primitiveConstructorNode(strandsContext, expectedType, returned);
|
|
132724
132803
|
return result.id;
|
|
@@ -132740,7 +132819,12 @@ function enforceReturnTypeMatch(strandsContext, expectedType, returned, hookName
|
|
|
132740
132819
|
};
|
|
132741
132820
|
if (receivedType.dimension !== expectedType.dimension) {
|
|
132742
132821
|
if (receivedType.dimension !== 1) {
|
|
132743
|
-
|
|
132822
|
+
const receivedTypeDisplay = receivedType.baseType + (receivedType.dimension > 1 ? receivedType.dimension : '');
|
|
132823
|
+
const expectedTypeDisplay = expectedType.baseType + expectedType.dimension;
|
|
132824
|
+
userError('type error',
|
|
132825
|
+
`You have returned a ${receivedTypeDisplay} in ${hookName} when a ${expectedTypeDisplay} was expected!\n\n` +
|
|
132826
|
+
`Make sure your hook returns the correct type.`
|
|
132827
|
+
);
|
|
132744
132828
|
}
|
|
132745
132829
|
else {
|
|
132746
132830
|
const result = primitiveConstructorNode(strandsContext, expectedType, returned);
|
|
@@ -132827,10 +132911,27 @@ function createShaderHooksFunctions(strandsContext, fn, shader) {
|
|
|
132827
132911
|
const handleRetVal = (retNode) => {
|
|
132828
132912
|
if(isStructType(expectedReturnType)) {
|
|
132829
132913
|
const expectedStructType = structType(expectedReturnType);
|
|
132830
|
-
if (retNode
|
|
132914
|
+
if (retNode?.isStrandsNode) {
|
|
132831
132915
|
const returnedNode = getNodeDataFromID(strandsContext.dag, retNode.id);
|
|
132832
132916
|
if (returnedNode.baseType !== expectedStructType.typeName) {
|
|
132833
|
-
|
|
132917
|
+
const receivedTypeName = returnedNode.baseType || 'undefined';
|
|
132918
|
+
const receivedDim = dag.dimensions[retNode.id];
|
|
132919
|
+
const receivedTypeDisplay = receivedDim > 1 ?
|
|
132920
|
+
`${receivedTypeName}${receivedDim}` : receivedTypeName;
|
|
132921
|
+
|
|
132922
|
+
const expectedProps = expectedStructType.properties
|
|
132923
|
+
.map(p => p.name).join(', ');
|
|
132924
|
+
userError('type error',
|
|
132925
|
+
`You have returned a ${receivedTypeDisplay} from ${hookType.name} when a ${expectedStructType.typeName} was expected.\n\n` +
|
|
132926
|
+
`The ${expectedStructType.typeName} struct has these properties: { ${expectedProps} }\n\n` +
|
|
132927
|
+
`Instead of returning a different type, you should modify and return the ${expectedStructType.typeName} struct that was passed to your hook.\n\n` +
|
|
132928
|
+
`For example:\n` +
|
|
132929
|
+
`${hookType.name}((inputs) => {\n` +
|
|
132930
|
+
` // Modify properties of inputs\n` +
|
|
132931
|
+
` inputs.someProperty = ...;\n` +
|
|
132932
|
+
` return inputs; // Return the modified struct\n` +
|
|
132933
|
+
`})`
|
|
132934
|
+
);
|
|
132834
132935
|
}
|
|
132835
132936
|
const newDeps = returnedNode.dependsOn.slice();
|
|
132836
132937
|
for (let i = 0; i < expectedStructType.properties.length; i++) {
|
|
@@ -132849,10 +132950,14 @@ function createShaderHooksFunctions(strandsContext, fn, shader) {
|
|
|
132849
132950
|
const propName = expectedProp.name;
|
|
132850
132951
|
const receivedValue = retNode[propName];
|
|
132851
132952
|
if (receivedValue === undefined) {
|
|
132852
|
-
|
|
132853
|
-
|
|
132854
|
-
|
|
132855
|
-
`
|
|
132953
|
+
const expectedProps = expectedReturnType.properties.map(p => p.name).join(', ');
|
|
132954
|
+
const receivedProps = Object.keys(retNode).join(', ');
|
|
132955
|
+
userError('type error',
|
|
132956
|
+
`You've returned an incomplete ${expectedStructType.typeName} struct from ${hookType.name}.\n\n` +
|
|
132957
|
+
`Expected properties: { ${expectedProps} }\n` +
|
|
132958
|
+
`Received properties: { ${receivedProps} }\n\n` +
|
|
132959
|
+
`All properties are required! Make sure to include all properties in the returned struct.`
|
|
132960
|
+
);
|
|
132856
132961
|
}
|
|
132857
132962
|
const expectedTypeInfo = expectedProp.dataType;
|
|
132858
132963
|
const returnedPropID = enforceReturnTypeMatch(strandsContext, expectedTypeInfo, receivedValue, hookType.name);
|