p5 2.2.2 → 2.2.3-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-BxjhKpTv.js → constants-D3ryGa0m.js} +1 -1
- package/dist/core/constants.js +1 -1
- package/dist/core/environment.js +7 -3
- 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 +2063 -2014
- package/dist/core/friendly_errors/sketch_verifier.js +1 -1
- 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 +11 -4
- package/dist/events/pointer.js +4 -0
- 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-w12-GSxu.js → ir_builders-DMfaOLIL.js} +48 -8
- package/dist/{main-DDs4QOnh.js → main-CGwYa9-f.js} +126 -36
- 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-BSGddFv7.js → p5.Renderer-C0e0XesC.js} +9 -2
- package/dist/{rendering-C9g7uSQ5.js → rendering-4Z2qdE_W.js} +90 -55
- 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/ir_dag.js +32 -2
- package/dist/strands/ir_types.js +18 -11
- package/dist/strands/p5.strands.js +15 -2
- package/dist/strands/strands_api.js +86 -40
- package/dist/strands/strands_conditionals.js +1 -1
- package/dist/strands/strands_for.js +1 -1
- package/dist/strands/strands_node.js +1 -1
- package/dist/strands/strands_phi_utils.js +27 -9
- package/dist/strands/strands_transpiler.js +1237 -831
- package/dist/type/index.js +2 -2
- package/dist/type/p5.Font.js +7 -5
- 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 +41 -35
- 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 +3 -3
- package/dist/webgl/utils.js +3 -3
- package/dist/webgpu/index.js +2 -2
- package/dist/webgpu/p5.RendererWebGPU.js +2 -2
- package/dist/webgpu/strands_wgslBackend.js +13 -4
- package/lib/p5.esm.js +3634 -2870
- package/lib/p5.esm.min.js +1 -1
- package/lib/p5.js +3634 -2870
- package/lib/p5.min.js +1 -1
- package/lib/p5.webgpu.esm.js +43 -15
- package/lib/p5.webgpu.js +43 -15
- package/lib/p5.webgpu.min.js +1 -1
- package/package.json +1 -1
- package/types/global.d.ts +805 -805
- package/types/p5.d.ts +415 -415
package/dist/strands/ir_types.js
CHANGED
|
@@ -37,6 +37,7 @@ const BaseType = {
|
|
|
37
37
|
BOOL: "bool",
|
|
38
38
|
MAT: "mat",
|
|
39
39
|
DEFER: "defer",
|
|
40
|
+
ASSIGN_ON_USE: "assign_on_use",
|
|
40
41
|
SAMPLER2D: "sampler2D",
|
|
41
42
|
SAMPLER: "sampler",
|
|
42
43
|
};
|
|
@@ -46,6 +47,7 @@ const BasePriority = {
|
|
|
46
47
|
[BaseType.BOOL]: 1,
|
|
47
48
|
[BaseType.MAT]: 0,
|
|
48
49
|
[BaseType.DEFER]: -1,
|
|
50
|
+
[BaseType.ASSIGN_ON_USE]: -2,
|
|
49
51
|
[BaseType.SAMPLER2D]: -10,
|
|
50
52
|
[BaseType.SAMPLER]: -11,
|
|
51
53
|
};
|
|
@@ -66,6 +68,7 @@ const DataType = {
|
|
|
66
68
|
mat3: { fnName: "mat3x3", baseType: BaseType.MAT, dimension:3, priority: 0, },
|
|
67
69
|
mat4: { fnName: "mat4x4", baseType: BaseType.MAT, dimension:4, priority: 0, },
|
|
68
70
|
defer: { fnName: null, baseType: BaseType.DEFER, dimension: null, priority: -1 },
|
|
71
|
+
assign_on_use: { fnName: null, baseType: BaseType.ASSIGN_ON_USE, dimension: null, priority: -2 },
|
|
69
72
|
sampler2D: { fnName: "sampler2D", baseType: BaseType.SAMPLER2D, dimension: 1, priority: -10 },
|
|
70
73
|
sampler: { fnName: "sampler", baseType: BaseType.SAMPLER, dimension: 1, priority: -11 },
|
|
71
74
|
};
|
|
@@ -137,7 +140,7 @@ const OpCode = {
|
|
|
137
140
|
}
|
|
138
141
|
};
|
|
139
142
|
const OperatorTable = [
|
|
140
|
-
{ arity: "unary", name: "not", symbol: "!", opCode: OpCode.Unary.LOGICAL_NOT },
|
|
143
|
+
{ arity: "unary", boolean: true, name: "not", symbol: "!", opCode: OpCode.Unary.LOGICAL_NOT },
|
|
141
144
|
{ arity: "unary", name: "neg", symbol: "-", opCode: OpCode.Unary.NEGATE },
|
|
142
145
|
{ arity: "unary", name: "plus", symbol: "+", opCode: OpCode.Unary.PLUS },
|
|
143
146
|
{ arity: "binary", name: "add", symbol: "+", opCode: OpCode.Binary.ADD },
|
|
@@ -145,14 +148,14 @@ const OperatorTable = [
|
|
|
145
148
|
{ arity: "binary", name: "mult", symbol: "*", opCode: OpCode.Binary.MULTIPLY },
|
|
146
149
|
{ arity: "binary", name: "div", symbol: "/", opCode: OpCode.Binary.DIVIDE },
|
|
147
150
|
{ arity: "binary", name: "mod", symbol: "%", opCode: OpCode.Binary.MODULO },
|
|
148
|
-
{ arity: "binary", name: "equalTo", symbol: "==", opCode: OpCode.Binary.EQUAL },
|
|
149
|
-
{ arity: "binary", name: "notEqual", symbol: "!=", opCode: OpCode.Binary.NOT_EQUAL },
|
|
150
|
-
{ arity: "binary", name: "greaterThan", symbol: ">", opCode: OpCode.Binary.GREATER_THAN },
|
|
151
|
-
{ arity: "binary", name: "greaterEqual", symbol: ">=", opCode: OpCode.Binary.GREATER_EQUAL },
|
|
152
|
-
{ arity: "binary", name: "lessThan", symbol: "<", opCode: OpCode.Binary.LESS_THAN },
|
|
153
|
-
{ arity: "binary", name: "lessEqual", symbol: "<=", opCode: OpCode.Binary.LESS_EQUAL },
|
|
154
|
-
{ arity: "binary", name: "and", symbol: "&&", opCode: OpCode.Binary.LOGICAL_AND },
|
|
155
|
-
{ arity: "binary", name: "or", symbol: "||", opCode: OpCode.Binary.LOGICAL_OR },
|
|
151
|
+
{ arity: "binary", boolean: true, name: "equalTo", symbol: "==", opCode: OpCode.Binary.EQUAL },
|
|
152
|
+
{ arity: "binary", boolean: true, name: "notEqual", symbol: "!=", opCode: OpCode.Binary.NOT_EQUAL },
|
|
153
|
+
{ arity: "binary", boolean: true, name: "greaterThan", symbol: ">", opCode: OpCode.Binary.GREATER_THAN },
|
|
154
|
+
{ arity: "binary", boolean: true, name: "greaterEqual", symbol: ">=", opCode: OpCode.Binary.GREATER_EQUAL },
|
|
155
|
+
{ arity: "binary", boolean: true, name: "lessThan", symbol: "<", opCode: OpCode.Binary.LESS_THAN },
|
|
156
|
+
{ arity: "binary", boolean: true, name: "lessEqual", symbol: "<=", opCode: OpCode.Binary.LESS_EQUAL },
|
|
157
|
+
{ arity: "binary", boolean: true, name: "and", symbol: "&&", opCode: OpCode.Binary.LOGICAL_AND },
|
|
158
|
+
{ arity: "binary", boolean: true, name: "or", symbol: "||", opCode: OpCode.Binary.LOGICAL_OR },
|
|
156
159
|
];
|
|
157
160
|
const ConstantFolding = {
|
|
158
161
|
[OpCode.Binary.ADD]: (a, b) => a + b,
|
|
@@ -173,7 +176,8 @@ const ConstantFolding = {
|
|
|
173
176
|
const OpCodeToSymbol = {};
|
|
174
177
|
const UnarySymbolToName = {};
|
|
175
178
|
const BinarySymbolToName = {};
|
|
176
|
-
|
|
179
|
+
const booleanOpCode = {};
|
|
180
|
+
for (const { symbol, opCode, name, arity, boolean } of OperatorTable) {
|
|
177
181
|
// SymbolToOpCode[symbol] = opCode;
|
|
178
182
|
OpCodeToSymbol[opCode] = symbol;
|
|
179
183
|
if (arity === 'unary') {
|
|
@@ -182,6 +186,9 @@ for (const { symbol, opCode, name, arity } of OperatorTable) {
|
|
|
182
186
|
if (arity === 'binary') {
|
|
183
187
|
BinarySymbolToName[symbol] = name;
|
|
184
188
|
}
|
|
189
|
+
if (boolean) {
|
|
190
|
+
booleanOpCode[opCode] = true;
|
|
191
|
+
}
|
|
185
192
|
}
|
|
186
193
|
const BlockType = {
|
|
187
194
|
GLOBAL: 'global',
|
|
@@ -200,4 +207,4 @@ const BlockTypeToName = Object.fromEntries(
|
|
|
200
207
|
Object.entries(BlockType).map(([key, val]) => [val, key])
|
|
201
208
|
);
|
|
202
209
|
|
|
203
|
-
export { BasePriority, BaseType, BinarySymbolToName, BlockType, BlockTypeToName, ConstantFolding, DataType, GenType, NodeType, NodeTypeRequiredFields, NodeTypeToName, OpCode, OpCodeToSymbol, OperatorTable, StatementType, TypeInfoFromGLSLName, UnarySymbolToName, isStructType, structType, typeEquals };
|
|
210
|
+
export { BasePriority, BaseType, BinarySymbolToName, BlockType, BlockTypeToName, ConstantFolding, DataType, GenType, NodeType, NodeTypeRequiredFields, NodeTypeToName, OpCode, OpCodeToSymbol, OperatorTable, StatementType, TypeInfoFromGLSLName, UnarySymbolToName, booleanOpCode, isStructType, structType, typeEquals };
|
|
@@ -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-
|
|
11
|
+
import '../ir_builders-DMfaOLIL.js';
|
|
12
12
|
import './strands_builtins.js';
|
|
13
13
|
import './strands_conditionals.js';
|
|
14
14
|
import './strands_phi_utils.js';
|
|
@@ -50,6 +50,7 @@ function strands(p5, fn) {
|
|
|
50
50
|
ctx.previousFES = p5.disableFriendlyErrors;
|
|
51
51
|
ctx.windowOverrides = {};
|
|
52
52
|
ctx.fnOverrides = {};
|
|
53
|
+
ctx.graphicsOverrides = {};
|
|
53
54
|
if (active) {
|
|
54
55
|
p5.disableFriendlyErrors = true;
|
|
55
56
|
}
|
|
@@ -72,6 +73,17 @@ function strands(p5, fn) {
|
|
|
72
73
|
for (const key in ctx.fnOverrides) {
|
|
73
74
|
fn[key] = ctx.fnOverrides[key];
|
|
74
75
|
}
|
|
76
|
+
// Clean up the hooks temporarily installed on p5.Graphics.prototype (#8549)
|
|
77
|
+
const GraphicsProto = p5.Graphics?.prototype;
|
|
78
|
+
if (GraphicsProto) {
|
|
79
|
+
for (const key in ctx.graphicsOverrides) {
|
|
80
|
+
if (ctx.graphicsOverrides[key] === undefined) {
|
|
81
|
+
delete GraphicsProto[key];
|
|
82
|
+
} else {
|
|
83
|
+
GraphicsProto[key] = ctx.graphicsOverrides[key];
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
75
87
|
}
|
|
76
88
|
|
|
77
89
|
const strandsContext = {};
|
|
@@ -640,7 +652,8 @@ if (typeof p5 !== "undefined") {
|
|
|
640
652
|
* filterColor.texCoord.x,
|
|
641
653
|
* filterColor.texCoord.y + 0.1 * sin(filterColor.texCoord.x * 10)
|
|
642
654
|
* ];
|
|
643
|
-
* filterColor.
|
|
655
|
+
* let tex = filterColor.canvasContent;
|
|
656
|
+
* filterColor.set(getTexture(tex, warped));
|
|
644
657
|
* filterColor.end();
|
|
645
658
|
* }
|
|
646
659
|
*
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { u as unaryOpNode, c as createStrandsNode,
|
|
1
|
+
import { u as unaryOpNode, c as createStrandsNode, S as StrandsNode, p as primitiveConstructorNode, v as variableNode, b as binaryOpNode, s as statementNode, f as functionCallNode, a as structInstanceNode, d as structConstructorNode } from '../ir_builders-DMfaOLIL.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';
|
|
@@ -101,6 +101,42 @@ function installBuiltinGlobalAccessors(strandsContext) {
|
|
|
101
101
|
strandsContext._builtinGlobalsAccessorsInstalled = true;
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
+
//////////////////////////////////////////////
|
|
105
|
+
// Prototype mirroring helpers
|
|
106
|
+
//////////////////////////////////////////////
|
|
107
|
+
|
|
108
|
+
/*
|
|
109
|
+
* Permanently augment both p5.prototype (fn) and p5.Graphics.prototype
|
|
110
|
+
* with a strands function. Overwrites unconditionally - strands wrappers
|
|
111
|
+
* are the correct dual mode implementation.
|
|
112
|
+
*/
|
|
113
|
+
function augmentFn(fn, p5, name, value) {
|
|
114
|
+
fn[name] = value;
|
|
115
|
+
const GraphicsProto = p5?.Graphics?.prototype;
|
|
116
|
+
if (GraphicsProto) {
|
|
117
|
+
GraphicsProto[name] = value;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/*
|
|
122
|
+
* Temporarily augment window, p5.prototype (fn), and p5.Graphics.prototype
|
|
123
|
+
* with a hook function. Saves previous values into strandsContext override
|
|
124
|
+
* stores so deinitStrandsContext can restore them.
|
|
125
|
+
*/
|
|
126
|
+
function augmentFnTemporary(fn, strandsContext, name, value) {
|
|
127
|
+
strandsContext.windowOverrides[name] = window[name];
|
|
128
|
+
strandsContext.fnOverrides[name] = fn[name];
|
|
129
|
+
window[name] = value;
|
|
130
|
+
fn[name] = value;
|
|
131
|
+
const GraphicsProto = strandsContext.p5?.Graphics?.prototype;
|
|
132
|
+
if (GraphicsProto) {
|
|
133
|
+
strandsContext.graphicsOverrides[name] = Object.prototype.hasOwnProperty.call(GraphicsProto, name)
|
|
134
|
+
? GraphicsProto[name]
|
|
135
|
+
: undefined;
|
|
136
|
+
GraphicsProto[name] = value;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
104
140
|
//////////////////////////////////////////////
|
|
105
141
|
// User nodes
|
|
106
142
|
//////////////////////////////////////////////
|
|
@@ -124,27 +160,27 @@ function initGlobalStrandsAPI(p5, fn, strandsContext) {
|
|
|
124
160
|
//////////////////////////////////////////////
|
|
125
161
|
// Unique Functions
|
|
126
162
|
//////////////////////////////////////////////
|
|
127
|
-
fn
|
|
163
|
+
augmentFn(fn, p5, 'discard', function() {
|
|
128
164
|
statementNode(strandsContext, StatementType.DISCARD);
|
|
129
|
-
};
|
|
130
|
-
fn
|
|
165
|
+
});
|
|
166
|
+
augmentFn(fn, p5, 'break', function() {
|
|
131
167
|
statementNode(strandsContext, StatementType.BREAK);
|
|
132
|
-
};
|
|
168
|
+
});
|
|
133
169
|
p5.break = fn.break;
|
|
134
|
-
fn
|
|
170
|
+
augmentFn(fn, p5, 'instanceID', function() {
|
|
135
171
|
const node = variableNode(strandsContext, { baseType: BaseType.INT, dimension: 1 }, strandsContext.backend.instanceIdReference());
|
|
136
172
|
return createStrandsNode(node.id, node.dimension, strandsContext);
|
|
137
|
-
};
|
|
173
|
+
});
|
|
138
174
|
// Internal methods use p5 static methods; user-facing methods use fn.
|
|
139
175
|
// Some methods need to be used by both.
|
|
140
176
|
p5.strandsIf = function(conditionNode, ifBody) {
|
|
141
177
|
return new StrandsConditional(strandsContext, conditionNode, ifBody);
|
|
142
178
|
};
|
|
143
|
-
fn
|
|
179
|
+
augmentFn(fn, p5, 'strandsIf', p5.strandsIf);
|
|
144
180
|
p5.strandsFor = function(initialCb, conditionCb, updateCb, bodyCb, initialVars) {
|
|
145
181
|
return new StrandsFor(strandsContext, initialCb, conditionCb, updateCb, bodyCb, initialVars).build();
|
|
146
182
|
};
|
|
147
|
-
fn
|
|
183
|
+
augmentFn(fn, p5, 'strandsFor', p5.strandsFor);
|
|
148
184
|
p5.strandsEarlyReturn = function(value) {
|
|
149
185
|
const { dag, cfg } = strandsContext;
|
|
150
186
|
|
|
@@ -177,7 +213,7 @@ function initGlobalStrandsAPI(p5, fn, strandsContext) {
|
|
|
177
213
|
|
|
178
214
|
return valueNode;
|
|
179
215
|
};
|
|
180
|
-
fn
|
|
216
|
+
augmentFn(fn, p5, 'strandsEarlyReturn', p5.strandsEarlyReturn);
|
|
181
217
|
p5.strandsNode = function(...args) {
|
|
182
218
|
if (args.length === 1 && args[0] instanceof StrandsNode) {
|
|
183
219
|
return args[0];
|
|
@@ -185,7 +221,20 @@ function initGlobalStrandsAPI(p5, fn, strandsContext) {
|
|
|
185
221
|
if (args.length > 4) {
|
|
186
222
|
userError("type error", "It looks like you've tried to construct a p5.strands node implicitly, with more than 4 components. This is currently not supported.");
|
|
187
223
|
}
|
|
188
|
-
|
|
224
|
+
// Filter out undefined/null values
|
|
225
|
+
const flatArgs = args.flat();
|
|
226
|
+
const definedArgs = flatArgs.filter(a => a !== undefined && a !== null);
|
|
227
|
+
|
|
228
|
+
// If all args are undefined, this is likely a `let myVar` at the
|
|
229
|
+
// start of an if statement and it will be assigned within the branches.
|
|
230
|
+
// For that, we use an assign-on-use node, meaning we'll take the type of the
|
|
231
|
+
// values assigned to it.
|
|
232
|
+
if (definedArgs.length === 0) {
|
|
233
|
+
const { id, dimension } = primitiveConstructorNode(strandsContext, { baseType: BaseType.ASSIGN_ON_USE, dimension: null }, [0]);
|
|
234
|
+
return createStrandsNode(id, dimension, strandsContext);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
const { id, dimension } = primitiveConstructorNode(strandsContext, { baseType: BaseType.FLOAT, dimension: null }, definedArgs);
|
|
189
238
|
return createStrandsNode(id, dimension, strandsContext);//new StrandsNode(id, dimension, strandsContext);
|
|
190
239
|
};
|
|
191
240
|
//////////////////////////////////////////////
|
|
@@ -195,16 +244,16 @@ function initGlobalStrandsAPI(p5, fn, strandsContext) {
|
|
|
195
244
|
const isp5Function = overrides[0].isp5Function;
|
|
196
245
|
if (isp5Function) {
|
|
197
246
|
const originalFn = fn[functionName];
|
|
198
|
-
fn
|
|
247
|
+
augmentFn(fn, p5, functionName, function(...args) {
|
|
199
248
|
if (strandsContext.active) {
|
|
200
249
|
const { id, dimension } = functionCallNode(strandsContext, functionName, args);
|
|
201
250
|
return createStrandsNode(id, dimension, strandsContext);
|
|
202
251
|
} else {
|
|
203
252
|
return originalFn.apply(this, args);
|
|
204
253
|
}
|
|
205
|
-
};
|
|
254
|
+
});
|
|
206
255
|
} else {
|
|
207
|
-
fn
|
|
256
|
+
augmentFn(fn, p5, functionName, function (...args) {
|
|
208
257
|
if (strandsContext.active) {
|
|
209
258
|
const { id, dimension } = functionCallNode(strandsContext, functionName, args);
|
|
210
259
|
return createStrandsNode(id, dimension, strandsContext);
|
|
@@ -213,11 +262,11 @@ function initGlobalStrandsAPI(p5, fn, strandsContext) {
|
|
|
213
262
|
`It looks like you've called ${functionName} outside of a shader's modify() function.`
|
|
214
263
|
);
|
|
215
264
|
}
|
|
216
|
-
};
|
|
265
|
+
});
|
|
217
266
|
}
|
|
218
267
|
}
|
|
219
268
|
|
|
220
|
-
fn
|
|
269
|
+
augmentFn(fn, p5, 'getTexture', function (...rawArgs) {
|
|
221
270
|
if (strandsContext.active) {
|
|
222
271
|
const { id, dimension } = strandsContext.backend.createGetTextureCall(strandsContext, rawArgs);
|
|
223
272
|
return createStrandsNode(id, dimension, strandsContext);
|
|
@@ -226,17 +275,17 @@ function initGlobalStrandsAPI(p5, fn, strandsContext) {
|
|
|
226
275
|
`It looks like you've called getTexture outside of a shader's modify() function.`
|
|
227
276
|
);
|
|
228
277
|
}
|
|
229
|
-
};
|
|
278
|
+
});
|
|
230
279
|
|
|
231
280
|
// Add texture function as alias for getTexture with p5 fallback
|
|
232
281
|
const originalTexture = fn.texture;
|
|
233
|
-
fn
|
|
282
|
+
augmentFn(fn, p5, 'texture', function (...args) {
|
|
234
283
|
if (strandsContext.active) {
|
|
235
284
|
return this.getTexture(...args);
|
|
236
285
|
} else {
|
|
237
286
|
return originalTexture.apply(this, args);
|
|
238
287
|
}
|
|
239
|
-
};
|
|
288
|
+
});
|
|
240
289
|
|
|
241
290
|
// Add noise function with backend-agnostic implementation
|
|
242
291
|
const originalNoise = fn.noise;
|
|
@@ -246,16 +295,16 @@ function initGlobalStrandsAPI(p5, fn, strandsContext) {
|
|
|
246
295
|
strandsContext._noiseOctaves = null;
|
|
247
296
|
strandsContext._noiseAmpFalloff = null;
|
|
248
297
|
|
|
249
|
-
fn
|
|
298
|
+
augmentFn(fn, p5, 'noiseDetail', function (lod, falloff = 0.5) {
|
|
250
299
|
if (!strandsContext.active) {
|
|
251
300
|
return originalNoiseDetail.apply(this, arguments);
|
|
252
301
|
}
|
|
253
302
|
|
|
254
303
|
strandsContext._noiseOctaves = lod;
|
|
255
304
|
strandsContext._noiseAmpFalloff = falloff;
|
|
256
|
-
};
|
|
305
|
+
});
|
|
257
306
|
|
|
258
|
-
fn
|
|
307
|
+
augmentFn(fn, p5, 'noise', function (...args) {
|
|
259
308
|
if (!strandsContext.active) {
|
|
260
309
|
return originalNoise.apply(this, args); // fallback to regular p5.js noise
|
|
261
310
|
}
|
|
@@ -302,9 +351,9 @@ function initGlobalStrandsAPI(p5, fn, strandsContext) {
|
|
|
302
351
|
}]
|
|
303
352
|
});
|
|
304
353
|
return createStrandsNode(id, dimension, strandsContext);
|
|
305
|
-
};
|
|
354
|
+
});
|
|
306
355
|
|
|
307
|
-
fn
|
|
356
|
+
augmentFn(fn, p5, 'millis', function (...args) {
|
|
308
357
|
if (!strandsContext.active) {
|
|
309
358
|
return originalMillis.apply(this, args);
|
|
310
359
|
}
|
|
@@ -317,14 +366,14 @@ function initGlobalStrandsAPI(p5, fn, strandsContext) {
|
|
|
317
366
|
return instance ? instance.millis() : undefined;
|
|
318
367
|
}
|
|
319
368
|
);
|
|
320
|
-
};
|
|
369
|
+
});
|
|
321
370
|
|
|
322
371
|
// Next is type constructors and uniform functions.
|
|
323
372
|
// For some of them, we have aliases so that you can write either a more human-readable
|
|
324
373
|
// variant or also one more directly translated from GLSL, or to be more compatible with
|
|
325
374
|
// APIs we documented at the release of 2.x and have to continue supporting.
|
|
326
375
|
for (const type in DataType) {
|
|
327
|
-
if (type === BaseType.DEFER || type === 'sampler') {
|
|
376
|
+
if (type === BaseType.DEFER || type === BaseType.ASSIGN_ON_USE || type === 'sampler') {
|
|
328
377
|
continue;
|
|
329
378
|
}
|
|
330
379
|
const typeInfo = DataType[type];
|
|
@@ -346,13 +395,13 @@ function initGlobalStrandsAPI(p5, fn, strandsContext) {
|
|
|
346
395
|
typeAliases.push(pascalTypeName.replace('Vec', 'Vector'));
|
|
347
396
|
}
|
|
348
397
|
}
|
|
349
|
-
fn
|
|
398
|
+
augmentFn(fn, p5, `uniform${pascalTypeName}`, function(name, defaultValue) {
|
|
350
399
|
const { id, dimension } = variableNode(strandsContext, typeInfo, name);
|
|
351
400
|
strandsContext.uniforms.push({ name, typeInfo, defaultValue });
|
|
352
401
|
return createStrandsNode(id, dimension, strandsContext);
|
|
353
|
-
};
|
|
402
|
+
});
|
|
354
403
|
// Shared variables with smart context detection
|
|
355
|
-
fn
|
|
404
|
+
augmentFn(fn, p5, `shared${pascalTypeName}`, function(name) {
|
|
356
405
|
const { id, dimension } = variableNode(strandsContext, typeInfo, name);
|
|
357
406
|
|
|
358
407
|
// Initialize shared variables tracking if not present
|
|
@@ -369,20 +418,20 @@ function initGlobalStrandsAPI(p5, fn, strandsContext) {
|
|
|
369
418
|
});
|
|
370
419
|
|
|
371
420
|
return createStrandsNode(id, dimension, strandsContext);
|
|
372
|
-
};
|
|
421
|
+
});
|
|
373
422
|
|
|
374
423
|
// Alias varying* as shared* for backward compatibility
|
|
375
|
-
fn
|
|
424
|
+
augmentFn(fn, p5, `varying${pascalTypeName}`, fn[`shared${pascalTypeName}`]);
|
|
376
425
|
|
|
377
426
|
for (const typeAlias of typeAliases) {
|
|
378
427
|
// For compatibility, also alias uniformVec2 as uniformVector2, what we initially
|
|
379
428
|
// documented these as
|
|
380
|
-
fn
|
|
381
|
-
fn
|
|
382
|
-
fn
|
|
429
|
+
augmentFn(fn, p5, `uniform${typeAlias}`, fn[`uniform${pascalTypeName}`]);
|
|
430
|
+
augmentFn(fn, p5, `varying${typeAlias}`, fn[`varying${pascalTypeName}`]);
|
|
431
|
+
augmentFn(fn, p5, `shared${typeAlias}`, fn[`shared${pascalTypeName}`]);
|
|
383
432
|
}
|
|
384
433
|
const originalp5Fn = fn[typeInfo.fnName];
|
|
385
|
-
fn
|
|
434
|
+
augmentFn(fn, p5, typeInfo.fnName, function(...args) {
|
|
386
435
|
if (strandsContext.active) {
|
|
387
436
|
if (args.length === 1 && args[0].dimension && args[0].dimension === typeInfo.dimension) {
|
|
388
437
|
const { id, dimension } = functionCallNode(
|
|
@@ -414,7 +463,7 @@ function initGlobalStrandsAPI(p5, fn, strandsContext) {
|
|
|
414
463
|
`It looks like you've called ${typeInfo.fnName} outside of a shader's modify() function.`
|
|
415
464
|
);
|
|
416
465
|
}
|
|
417
|
-
};
|
|
466
|
+
});
|
|
418
467
|
}
|
|
419
468
|
}
|
|
420
469
|
//////////////////////////////////////////////
|
|
@@ -695,10 +744,7 @@ function createShaderHooksFunctions(strandsContext, fn, shader) {
|
|
|
695
744
|
}
|
|
696
745
|
|
|
697
746
|
for (const name of aliases) {
|
|
698
|
-
strandsContext
|
|
699
|
-
strandsContext.fnOverrides[name] = fn[name];
|
|
700
|
-
window[name] = hook;
|
|
701
|
-
fn[name] = hook;
|
|
747
|
+
augmentFnTemporary(fn, strandsContext, name, hook);
|
|
702
748
|
}
|
|
703
749
|
hook.earlyReturns = [];
|
|
704
750
|
}
|
|
@@ -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-
|
|
4
|
+
import { c as createStrandsNode } from '../ir_builders-DMfaOLIL.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, p as primitiveConstructorNode } from '../ir_builders-
|
|
4
|
+
import { c as createStrandsNode, p as primitiveConstructorNode } from '../ir_builders-DMfaOLIL.js';
|
|
5
5
|
import { createPhiNode } from './strands_phi_utils.js';
|
|
6
6
|
import './strands_FES.js';
|
|
7
7
|
import './strands_builtins.js';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { recordInBasicBlock } from './ir_cfg.js';
|
|
2
|
-
import { getNodeDataFromID, getOrCreateNode } from './ir_dag.js';
|
|
3
|
-
import { NodeType } from './ir_types.js';
|
|
2
|
+
import { getNodeDataFromID, propagateTypeToAssignOnUse, getOrCreateNode } from './ir_dag.js';
|
|
3
|
+
import { BaseType, NodeType } from './ir_types.js';
|
|
4
4
|
import './strands_FES.js';
|
|
5
5
|
|
|
6
6
|
function createPhiNode(strandsContext, phiInputs, varName) {
|
|
@@ -9,13 +9,31 @@ function createPhiNode(strandsContext, phiInputs, varName) {
|
|
|
9
9
|
if (validInputs.length === 0) {
|
|
10
10
|
throw new Error(`No valid inputs for phi node for variable ${varName}`);
|
|
11
11
|
}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
12
|
+
|
|
13
|
+
// Get dimension and baseType from first valid input, skipping ASSIGN_ON_USE nodes
|
|
14
|
+
const inputNodes = validInputs.map((input) => getNodeDataFromID(strandsContext.dag, input.value.id));
|
|
15
|
+
|
|
16
|
+
// Find first non-ASSIGN_ON_USE input to determine type
|
|
17
|
+
let typeSource = inputNodes.find((input) => input.baseType !== BaseType.ASSIGN_ON_USE && input.dimension) ??
|
|
18
|
+
inputNodes.find((input) => input.baseType !== BaseType.ASSIGN_ON_USE);
|
|
19
|
+
|
|
20
|
+
// If all are ASSIGN_ON_USE, fall back to first input
|
|
21
|
+
if (!typeSource) {
|
|
22
|
+
typeSource = inputNodes[0];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const dimension = typeSource.dimension;
|
|
26
|
+
const baseType = typeSource.baseType;
|
|
27
|
+
|
|
28
|
+
// Propagate the type to all ASSIGN_ON_USE inputs
|
|
29
|
+
if (baseType !== BaseType.ASSIGN_ON_USE) {
|
|
30
|
+
for (const input of inputNodes) {
|
|
31
|
+
if (input.baseType === BaseType.ASSIGN_ON_USE) {
|
|
32
|
+
propagateTypeToAssignOnUse(strandsContext.dag, input.id, baseType, dimension);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
19
37
|
const nodeData = {
|
|
20
38
|
nodeType: NodeType.PHI,
|
|
21
39
|
dimension,
|