Skip to content

Commit 3e6e25b

Browse files
authored
Merge branch 'dev-2.0' into fix/minified-strands
2 parents 20dbb7f + 9512db6 commit 3e6e25b

2 files changed

Lines changed: 91 additions & 0 deletions

File tree

src/strands/strands_transpiler.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,37 @@ const ASTCallbacks = {
271271
};
272272
node.arguments = [node.right];
273273
},
274+
LogicalExpression(node, _state, ancestors) {
275+
// Don't convert uniform default values to node methods, as
276+
// they should be evaluated at runtime, not compiled.
277+
if (ancestors.some(nodeIsUniform)) { return; }
278+
// If the left hand side of an expression is one of these types,
279+
// we should construct a node from it.
280+
const unsafeTypes = ['Literal', 'ArrayExpression', 'Identifier'];
281+
if (unsafeTypes.includes(node.left.type)) {
282+
const leftReplacementNode = {
283+
type: 'CallExpression',
284+
callee: {
285+
type: 'Identifier',
286+
name: '__p5.strandsNode',
287+
},
288+
arguments: [node.left]
289+
}
290+
node.left = leftReplacementNode;
291+
}
292+
// Replace the logical operator with a call expression
293+
// in other words a call to BaseNode.or(), .and() etc.
294+
node.type = 'CallExpression';
295+
node.callee = {
296+
type: 'MemberExpression',
297+
object: node.left,
298+
property: {
299+
type: 'Identifier',
300+
name: replaceBinaryOperator(node.operator),
301+
},
302+
};
303+
node.arguments = [node.right];
304+
},
274305
IfStatement(node, _state, ancestors) {
275306
if (ancestors.some(nodeIsUniform)) { return; }
276307
// Transform if statement into strandsIf() call

test/unit/webgl/p5.Shader.js

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -714,6 +714,66 @@ suite('p5.Shader', function() {
714714
assert.approximately(pixelColor[1], 255, 5); // Green channel should be 255
715715
assert.approximately(pixelColor[2], 255, 5); // Blue channel should be 255
716716
});
717+
test('handle if statement with || (OR) operator', () => {
718+
myp5.createCanvas(50, 50, myp5.WEBGL);
719+
const testShader = myp5.baseMaterialShader().modify(() => {
720+
myp5.getPixelInputs(inputs => {
721+
let c = [1, 1, 1, 1];
722+
if (myp5.abs(inputs.texCoord.x - 0.5) > 0.2 || myp5.abs(inputs.texCoord.y - 0.5) > 0.2) {
723+
c = [1, 0, 0, 1];
724+
}
725+
inputs.color = c;
726+
return inputs;
727+
});
728+
}, { myp5 });
729+
myp5.noStroke();
730+
myp5.shader(testShader);
731+
myp5.plane(myp5.width, myp5.height);
732+
const centerPixel = myp5.get(25, 25);
733+
assert.approximately(centerPixel[0], 255, 5);
734+
assert.approximately(centerPixel[1], 255, 5);
735+
assert.approximately(centerPixel[2], 255, 5);
736+
const leftEdgePixel = myp5.get(5, 25);
737+
assert.approximately(leftEdgePixel[0], 255, 5);
738+
assert.approximately(leftEdgePixel[1], 0, 5);
739+
assert.approximately(leftEdgePixel[2], 0, 5);
740+
const topEdgePixel = myp5.get(25, 5);
741+
assert.approximately(topEdgePixel[0], 255, 5);
742+
assert.approximately(topEdgePixel[1], 0, 5);
743+
assert.approximately(topEdgePixel[2], 0, 5);
744+
});
745+
test('handle if statement with && (AND) operator', () => {
746+
myp5.createCanvas(50, 50, myp5.WEBGL);
747+
const testShader = myp5.baseMaterialShader().modify(() => {
748+
myp5.getPixelInputs(inputs => {
749+
let color = myp5.float(0.0);
750+
if (inputs.texCoord.x > 0.5 && inputs.texCoord.y > 0.5) {
751+
color = myp5.float(1.0);
752+
}
753+
inputs.color = [color, color, color, 1.0];
754+
return inputs;
755+
});
756+
}, { myp5 });
757+
myp5.noStroke();
758+
myp5.shader(testShader);
759+
myp5.plane(myp5.width, myp5.height);
760+
const bottomRightPixel = myp5.get(45, 45);
761+
assert.approximately(bottomRightPixel[0], 255, 5);
762+
assert.approximately(bottomRightPixel[1], 255, 5);
763+
assert.approximately(bottomRightPixel[2], 255, 5);
764+
const topLeftPixel = myp5.get(5, 5);
765+
assert.approximately(topLeftPixel[0], 0, 5);
766+
assert.approximately(topLeftPixel[1], 0, 5);
767+
assert.approximately(topLeftPixel[2], 0, 5);
768+
const topRightPixel = myp5.get(45, 5);
769+
assert.approximately(topRightPixel[0], 0, 5);
770+
assert.approximately(topRightPixel[1], 0, 5);
771+
assert.approximately(topRightPixel[2], 0, 5);
772+
const bottomLeftPixel = myp5.get(5, 45);
773+
assert.approximately(bottomLeftPixel[0], 0, 5);
774+
assert.approximately(bottomLeftPixel[1], 0, 5);
775+
assert.approximately(bottomLeftPixel[2], 0, 5);
776+
});
717777
// Keep one direct API test for completeness
718778
test('handle direct StrandsIf API usage', () => {
719779
myp5.createCanvas(50, 50, myp5.WEBGL);

0 commit comments

Comments
 (0)