From d837166a1ba012d538d29fb153f0733de15e25c3 Mon Sep 17 00:00:00 2001 From: Olivier Guyot Date: Tue, 22 Oct 2019 22:44:11 +0200 Subject: [PATCH] Literal Style / add new math operators --- src/ol/style/LiteralStyle.js | 4 ++++ src/ol/webgl/ShaderBuilder.js | 17 +++++++++++++++-- test/spec/ol/webgl/shaderbuilder.test.js | 4 ++++ 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/ol/style/LiteralStyle.js b/src/ol/style/LiteralStyle.js index b4cb84e320..c0ee1e085a 100644 --- a/src/ol/style/LiteralStyle.js +++ b/src/ol/style/LiteralStyle.js @@ -18,10 +18,14 @@ * * * Math operators: * * `['*', value1, value1]` multiplies `value1` by `value2` + * * `['/', value1, value1]` divides `value1` by `value2` * * `['+', value1, value1]` adds `value1` and `value2` + * * `['-', value1, value1]` subtracts `value2` from `value1` * * `['clamp', value, low, high]` clamps `value` between `low` and `high` * * `['stretch', value, low1, high1, low2, high2]` maps `value` from [`low1`, `high1`] range to * [`low2`, `high2`] range, clamping values along the way + * * `['mod', value1, value1]` returns the result of `value1 % value2` (modulo) + * * `['pow', value1, value1]` returns the value of `value1` raised to the `value2` power * * * Color operators: * * `['interpolate', ratio, color1, color2]` returns a color through interpolation between `color1` and diff --git a/src/ol/webgl/ShaderBuilder.js b/src/ol/webgl/ShaderBuilder.js index 1b2efde7c2..2c58fd70b5 100644 --- a/src/ol/webgl/ShaderBuilder.js +++ b/src/ol/webgl/ShaderBuilder.js @@ -87,9 +87,13 @@ function getValueType(value) { case 'var': case 'time': case '*': + case '/': case '+': + case '-': case 'clamp': case 'stretch': + case 'mod': + case 'pow': case '>': case '>=': case '<': @@ -172,7 +176,11 @@ export function check(value) { case 'time': break; case '*': + case '/': case '+': + case '-': + case 'mod': + case 'pow': checkNumber(v[1]); checkNumber(v[2]); break; @@ -271,8 +279,11 @@ export function parse(value, attributes, attributePrefix, variables, typeHint) { return 'u_time'; // math operators - case '*': return `(${p(v[1])} * ${p(v[2])})`; - case '+': return `(${p(v[1])} + ${p(v[2])})`; + case '*': + case '/': + case '+': + case '-': + return `(${p(v[1])} ${v[0]} ${p(v[2])})`; case 'clamp': return `clamp(${p(v[1])}, ${p(v[2])}, ${p(v[3])})`; case 'stretch': const low1 = p(v[2]); @@ -280,6 +291,8 @@ export function parse(value, attributes, attributePrefix, variables, typeHint) { const low2 = p(v[4]); const high2 = p(v[5]); return `((clamp(${p(v[1])}, ${low1}, ${high1}) - ${low1}) * ((${high2} - ${low2}) / (${high1} - ${low1})) + ${low2})`; + case 'mod': return `mod(${p(v[1])}, ${p(v[2])})`; + case 'pow': return `pow(${p(v[1])}, ${p(v[2])})`; // color operators case 'interpolate': diff --git a/test/spec/ol/webgl/shaderbuilder.test.js b/test/spec/ol/webgl/shaderbuilder.test.js index 86ed2c9b48..bc94e59bdc 100644 --- a/test/spec/ol/webgl/shaderbuilder.test.js +++ b/test/spec/ol/webgl/shaderbuilder.test.js @@ -279,8 +279,10 @@ void main(void) { check(['var', 'myValue']); check(['time']); check(['+', ['*', ['get', 'size'], 0.001], 12]); + check(['/', ['-', ['get', 'size'], 0.001], 12]); check(['clamp', ['get', 'attr2'], ['get', 'attr3'], 20]); check(['stretch', ['get', 'size'], 10, 100, 4, 8]); + check(['mod', ['pow', ['get', 'size'], 0.5], 12]); check(['>', 10, ['get', 'attr4']]); check(['>=', 10, ['get', 'attr4']]); check(['<', 10, ['get', 'attr4']]); @@ -381,8 +383,10 @@ void main(void) { expect(parseFn(['var', 'myValue'])).to.eql('u_myValue'); expect(parseFn(['time'])).to.eql('u_time'); expect(parseFn(['+', ['*', ['get', 'size'], 0.001], 12])).to.eql('((a_size * 0.001) + 12.0)'); + expect(parseFn(['/', ['-', ['get', 'size'], 20], 100])).to.eql('((a_size - 20.0) / 100.0)'); expect(parseFn(['clamp', ['get', 'attr2'], ['get', 'attr3'], 20])).to.eql('clamp(a_attr2, a_attr3, 20.0)'); expect(parseFn(['stretch', ['get', 'size'], 10, 100, 4, 8])).to.eql('((clamp(a_size, 10.0, 100.0) - 10.0) * ((8.0 - 4.0) / (100.0 - 10.0)) + 4.0)'); + expect(parseFn(['pow', ['mod', ['time'], 10], 2])).to.eql('pow(mod(u_time, 10.0), 2.0)'); expect(parseFn(['>', 10, ['get', 'attr4']])).to.eql('(10.0 > a_attr4 ? 1.0 : 0.0)'); expect(parseFn(['>=', 10, ['get', 'attr4']])).to.eql('(10.0 >= a_attr4 ? 1.0 : 0.0)'); expect(parseFn(['<', 10, ['get', 'attr4']])).to.eql('(10.0 < a_attr4 ? 1.0 : 0.0)');