Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More unary fns for 3d-tiles #4775

Merged
merged 32 commits into from
Jan 13, 2017
Merged
Show file tree
Hide file tree
Changes from 37 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
ffd91d1
Merge remote-tracking branch 'refs/remotes/AnalyticalGraphicsInc/3d-t…
leesafini Dec 19, 2016
3592d81
Merge remote-tracking branch 'refs/remotes/origin/binaryfns' into una…
leesafini Dec 19, 2016
888a454
begin adding unary fns
leesafini Dec 19, 2016
d9fbc91
added fract to CesiumMath library
leesafini Dec 20, 2016
a3be0fb
added tests for fract to MathSpec
leesafini Dec 20, 2016
2d3dd6e
added tests in expressionspec
leesafini Dec 20, 2016
8d7e29d
added tests for fract to expressionspec
leesafini Dec 20, 2016
9591c46
added shader tests
leesafini Dec 20, 2016
ba682da
added sandcastle demos
leesafini Dec 20, 2016
d2ac9f3
some updates
leesafini Dec 20, 2016
cd6b804
changed exp2 to CesiumMath
leesafini Dec 20, 2016
664bf5c
some updates
leesafini Dec 20, 2016
bfe278c
fixed more conflicts
leesafini Dec 20, 2016
e9fd5e1
fixed whitespace
leesafini Dec 20, 2016
59e2209
fixed more conflicts
leesafini Dec 20, 2016
883dc4d
more conflicts
leesafini Dec 20, 2016
e6e37ac
package newline?
leesafini Dec 20, 2016
7210fbd
final conflicts maybe
leesafini Dec 20, 2016
7e390ea
last changes to remove extra files
leesafini Dec 20, 2016
8cb17a6
moving fract and exp2 from CesiumMath to Expression
leesafini Jan 6, 2017
0c1313e
removed CesiumMath tests
leesafini Jan 6, 2017
c2eb1ec
trying to fix round
leesafini Jan 12, 2017
0635a06
moved exp2 and fract to Expression
leesafini Jan 12, 2017
7e85fd4
resolving merge conflicts
leesafini Jan 12, 2017
1bf372e
round working
leesafini Jan 12, 2017
034b4f1
changed round case to only shader area
leesafini Jan 12, 2017
6945d48
Merge branch '3d-tiles' into unaryfns
lilleyse Jan 12, 2017
eaaa724
Fix up merge
lilleyse Jan 12, 2017
af2704f
changes made per reviewed
leesafini Jan 12, 2017
9e8ee76
fixed tests
leesafini Jan 13, 2017
7650e3d
round test
leesafini Jan 13, 2017
792d246
more round testing
leesafini Jan 13, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions Apps/Sandcastle/gallery/3D Tiles Point Cloud Styling.html
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,26 @@
pointSize : "5"
});

addStyle('Sign', {
color : "color() * sign(${temperature})",
pointSize : "5"
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since temperature is always positive this style won't look very special. One idea could be using the sign of the ${POSITIONS} values (like the tests below).

Copy link
Contributor

@lilleyse lilleyse Jan 12, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a reminder about this comment. fract sort of applies here too. Even just sign(${temperature} - 0.5) may be sufficient.


addStyle('Rounding Functions', {
color : "rgb(floor(${POSITION}[0]) * 255, ceil(${POSITION}[1]) * 255, round(${POSITION}[2]) * 255)",
pointSize : "5"
});

addStyle('Exp and Log Functions', {
color : "rgb(log(${POSITION}[0]) * 255, log2(${POSITION}[1]) * 255 + exp2(${POSITION}[1]) * 255, exp(${POSITION}[2]) * 255)",
pointSize : "5"
});

addStyle('Fractional Part', {
color : "color() * fract(${temperature})",
pointSize : "5"
});

addStyle('Pow', {
color : "color() * pow(${temperature}, 3)",
pointSize : "5"
Expand Down
45 changes: 43 additions & 2 deletions Source/Scene/Expression.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,15 @@ define([
asin : Math.asin,
atan : Math.atan,
radians : CesiumMath.toRadians,
degrees : CesiumMath.toDegrees
degrees : CesiumMath.toDegrees,
sign : Math.sign,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use CesiumMath.sign instead. Looking here Math.sign isn't supported in all browsers: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sign.

floor : Math.floor,
ceil : Math.ceil,
exp : Math.exp,
exp2 : exp2,
log : Math.log,
log2 : Math.log2,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It turns out this is also not supported for IE. log2 will also need to be a local function which can use CesiumMath.logBase.

fract : fract
};

/**
Expand Down Expand Up @@ -362,6 +370,29 @@ define([
}
val = createRuntimeAst(expression, args[0]);
return new Node(ExpressionNodeType.UNARY, call, val);
} else if (call === 'round') {
//>>includeStart('debug', pragmas.debug);
if (args.length < 1 || args.length > 1) {
throw new DeveloperError('Error: ' + call + ' requires exactly one argument.');
}
//>>includeEnd('debug');
val = createRuntimeAst(expression, args[0]);
return new Node(ExpressionNodeType.UNARY, call, val);
} else if (call === 'isExactClass' || call === 'isClass') {
//>>includeStart('debug', pragmas.debug);
if (argsLength < 1 || argsLength > 1) {
throw new DeveloperError('Error: ' + call + ' requires exactly one argument.');
}
//>>includeEnd('debug');
val = createRuntimeAst(expression, args[0]);
return new Node(ExpressionNodeType.UNARY, call, val);
} else if (call === 'getExactClassName') {
//>>includeStart('debug', pragmas.debug);
if (argsLength > 0) {
throw new DeveloperError('Error: ' + call + ' does not take any argument.');
}
//>>includeEnd('debug');
return new Node(ExpressionNodeType.UNARY, call);
} else if (defined(unaryFunctions[call])) {
//>>includeStart('debug', pragmas.debug);
if (args.length < 1 || args.length > 1) {
Expand Down Expand Up @@ -1119,7 +1150,15 @@ define([
return expressions;
}

Node.prototype.getShaderExpression = function(attributePrefix, shaderState) {
function fract(number) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Place these functions closer to the top, maybe right before var binaryFunctions = {.

return number - Math.floor(number);
}

function exp2(exponent) {
return Math.pow(2.0,exponent);
}

Node.prototype.getShaderExpression = function(attributePrefix, shaderState, parent) {
var color;
var left;
var right;
Expand Down Expand Up @@ -1184,6 +1223,8 @@ define([
return 'bool(' + left + ')';
} else if (value === 'Number') {
return 'float(' + left + ')';
} else if (value === 'round') {
return 'floor(' + left + '0.5)';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Try 'floor(' + left + ' + 0.5)';

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hahaha oof, that fixed it. Sorry!

} else if (defined(unaryFunctions[value])) {
return value + '(' + left + ')';
} else if (value === 'abs') {
Expand Down
258 changes: 258 additions & 0 deletions Specs/Scene/ExpressionSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -988,6 +988,189 @@ defineSuite([
}).toThrowDeveloperError();
});

it('evaluates sign function', function() {
var expression = new Expression('sign(5.0)');
expect(expression.evaluate(frameState, undefined)).toEqual(1.0);

expression = new Expression('sign(0.0)');
expect(expression.evaluate(frameState, undefined)).toEqual(0.0);

expression = new Expression('sign(-5.0)');
expect(expression.evaluate(frameState, undefined)).toEqual(-1.0);
});

it('throws if sign function takes an invalid number of arguments', function() {
expect(function() {
return new Expression('sign()');
}).toThrowDeveloperError();

expect(function() {
return new Expression('sign(1, 2)');
}).toThrowDeveloperError();
});

it('evaluates floor function', function() {
var expression = new Expression('floor(5.5)');
expect(expression.evaluate(frameState, undefined)).toEqual(5.0);

expression = new Expression('floor(0.0)');
expect(expression.evaluate(frameState, undefined)).toEqual(0.0);

expression = new Expression('floor(-1.2)');
expect(expression.evaluate(frameState, undefined)).toEqual(-2.0);
});

it('throws if floor function takes an invalid number of arguments', function() {
expect(function() {
return new Expression('floor()');
}).toThrowDeveloperError();

expect(function() {
return new Expression('floor(1, 2)');
}).toThrowDeveloperError();
});

it('evaluates ceil function', function() {
var expression = new Expression('ceil(5.5)');
expect(expression.evaluate(frameState, undefined)).toEqual(6.0);

expression = new Expression('ceil(0.0)');
expect(expression.evaluate(frameState, undefined)).toEqual(0.0);

expression = new Expression('ceil(-1.2)');
expect(expression.evaluate(frameState, undefined)).toEqual(-1.0);
});

it('throws if ceil function takes an invalid number of arguments', function() {
expect(function() {
return new Expression('ceil()');
}).toThrowDeveloperError();

expect(function() {
return new Expression('ceil(1, 2)');
}).toThrowDeveloperError();
});

it('evaluates round function', function() {
var expression = new Expression('round(5.5)');
expect(expression.evaluate(frameState, undefined)).toEqual(6);

expression = new Expression('round(0.0)');
expect(expression.evaluate(frameState, undefined)).toEqual(0);

expression = new Expression('round(1.2)');
expect(expression.evaluate(frameState, undefined)).toEqual(1);
});

it('throws if round function takes an invalid number of arguments', function() {
expect(function() {
return new Expression('round()');
}).toThrowDeveloperError();

expect(function() {
return new Expression('round(1, 2)');
}).toThrowDeveloperError();
});

it('evaluates exp function', function() {
var expression = new Expression('exp(1.0)');
expect(expression.evaluate(frameState, undefined)).toEqual(Math.E);

expression = new Expression('exp(0.0)');
expect(expression.evaluate(frameState, undefined)).toEqual(1.0);
});

it('throws if exp function takes an invalid number of arguments', function() {
expect(function() {
return new Expression('exp()');
}).toThrowDeveloperError();

expect(function() {
return new Expression('exp(1, 2)');
}).toThrowDeveloperError();
});

it('evaluates exp2 function', function() {
var expression = new Expression('exp2(1.0)');
expect(expression.evaluate(frameState, undefined)).toEqual(2.0);

expression = new Expression('exp2(0.0)');
expect(expression.evaluate(frameState, undefined)).toEqual(1.0);

expression = new Expression('exp2(2.0)');
expect(expression.evaluate(frameState, undefined)).toEqual(4.0);
});

it('throws if exp2 function takes an invalid number of arguments', function() {
expect(function() {
return new Expression('exp2()');
}).toThrowDeveloperError();

expect(function() {
return new Expression('exp2(1, 2)');
}).toThrowDeveloperError();
});

it('evaluates log function', function() {
var expression = new Expression('log(1.0)');
expect(expression.evaluate(frameState, undefined)).toEqual(0.0);

expression = new Expression('log(Math.E)');
expect(expression.evaluate(frameState, undefined)).toEqual(1.0);
});

it('throws if log function takes an invalid number of arguments', function() {
expect(function() {
return new Expression('log()');
}).toThrowDeveloperError();

expect(function() {
return new Expression('log(1, 2)');
}).toThrowDeveloperError();
});

it('evaluates log2 function', function() {
var expression = new Expression('log2(1.0)');
expect(expression.evaluate(frameState, undefined)).toEqual(0.0);

expression = new Expression('log2(2.0)');
expect(expression.evaluate(frameState, undefined)).toEqual(1.0);

expression = new Expression('log2(4.0)');
expect(expression.evaluate(frameState, undefined)).toEqual(2.0);
});

it('throws if log2 function takes an invalid number of arguments', function() {
expect(function() {
return new Expression('log2()');
}).toThrowDeveloperError();

expect(function() {
return new Expression('log2(1, 2)');
}).toThrowDeveloperError();
});

it('evaluates fract function', function() {
var expression = new Expression('fract(1.0)');
expect(expression.evaluate(frameState, undefined)).toEqual(0.0);

expression = new Expression('fract(2.25)');
expect(expression.evaluate(frameState, undefined)).toEqual(0.25);

expression = new Expression('fract(-2.25)');
expect(expression.evaluate(frameState, undefined)).toEqual(0.75);
});

it('throws if fract function takes an invalid number of arguments', function() {
expect(function() {
return new Expression('log2()');
}).toThrowDeveloperError();

expect(function() {
return new Expression('log2(1, 2)');
}).toThrowDeveloperError();
});

it('evaluates atan2 function', function() {
var expression = new Expression('atan2(0,1)');
expect(expression.evaluate(frameState, undefined)).toEqualEpsilon(0.0, CesiumMath.EPSILON10);
Expand Down Expand Up @@ -1879,6 +2062,81 @@ defineSuite([
expect(shaderExpression).toEqual(expected);
});

it('gets shader expression for sign', function() {
var expression = new Expression('sign(1.0)');
var shaderExpression = expression.getShaderExpression('', {});
var expected = 'sign(1.0)';
expect(shaderExpression).toEqual(expected);
});

it('gets shader expression for floor', function() {
var expression = new Expression('floor(1.5)');
var shaderExpression = expression.getShaderExpression('', {});
var expected = 'floor(1.5)';
expect(shaderExpression).toEqual(expected);
});

it('gets shader expression for ceil', function() {
var expression = new Expression('ceil(1.2)');
var shaderExpression = expression.getShaderExpression('', {});
var expected = 'ceil(1.2)';
expect(shaderExpression).toEqual(expected);
});

it('gets shader expression for round', function() {
var expression = new Expression('round(1.2)');
var shaderExpression = expression.getShaderExpression('', {});
var expected = 'round(1.2)';
expect(shaderExpression).toEqual(expected);
});

it('gets shader expression for exp', function() {
var expression = new Expression('exp(1.0)');
var shaderExpression = expression.getShaderExpression('', {});
var expected = 'exp(1.0)';
expect(shaderExpression).toEqual(expected);
});

it('gets shader expression for exp2', function() {
var expression = new Expression('exp2(1.0)');
var shaderExpression = expression.getShaderExpression('', {});
var expected = 'exp2(1.0)';
expect(shaderExpression).toEqual(expected);
});

it('gets shader expression for log', function() {
var expression = new Expression('log(1.0)');
var shaderExpression = expression.getShaderExpression('', {});
var expected = 'log(1.0)';
expect(shaderExpression).toEqual(expected);
});

it('gets shader expression for log2', function() {
var expression = new Expression('log2(1.0)');
var shaderExpression = expression.getShaderExpression('', {});
var expected = 'log2(1.0)';
expect(shaderExpression).toEqual(expected);
});

it('gets shader expression for fract', function() {
var expression = new Expression('fract(1.0)');
var shaderExpression = expression.getShaderExpression('', {});
var expected = 'fract(1.0)';
expect(shaderExpression).toEqual(expected);
});

it('gets shader expression for clamp', function() {
var expression = new Expression('clamp(50.0, 0.0, 100.0)');
var shaderExpression = expression.getShaderExpression('', {});
var expected = 'clamp(50.0, 0.0, 100.0)';
expect(shaderExpression).toEqual(expected);
});

it('gets shader expression for mix', function() {
var expression = new Expression('mix(0.0, 2.0, 0.5)');
var shaderExpression = expression.getShaderExpression('', {});
var expected = 'mix(0.0, 2.0, 0.5)';

it('gets shader expression for atan2', function() {
var expression = new Expression('atan2(0.0,1.0)');
var shaderExpression = expression.getShaderExpression('', {});
Expand Down