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

3D Tiles Styling - treat colors as vec4 #4849

Merged
merged 3 commits into from
Jan 12, 2017
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
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
124 changes: 41 additions & 83 deletions Source/Scene/Expression.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,6 @@ define([
var scratchColor = new Color();

var ScratchStorage = {
scratchColorIndex : 0,
scratchColorArray : [new Color()],
scratchArrayIndex : 0,
scratchArrayArray : [[]],
scratchCartesian2Index : 0,
Expand All @@ -47,18 +45,11 @@ define([
scratchCartesian3Array : [new Cartesian3()],
scratchCartesian4Array : [new Cartesian4()],
reset : function() {
this.scratchColorIndex = 0;
this.scratchArrayIndex = 0;
this.scratchCartesian2Index = 0;
this.scratchCartesian3Index = 0;
this.scratchCartesian4Index = 0;
},
getColor : function() {
if (this.scratchColorIndex >= this.scratchColorArray.length) {
this.scratchColorArray.push(new Color());
}
return this.scratchColorArray[this.scratchColorIndex++];
},
getArray : function() {
if (this.scratchArrayIndex >= this.scratchArrayArray.length) {
this.scratchArrayArray.push([]);
Expand Down Expand Up @@ -184,18 +175,17 @@ define([
* {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/tree/master/Styling|3D Tiles Styling language}
* is of type <code>Boolean</code>, <code>Number</code>, or <code>String</code>, the corresponding JavaScript
* primitive type will be returned. If the result is a <code>RegExp</code>, a Javascript <code>RegExp</code>
* object will be returned. If the result is a <code>Color</code>, a {@link Color} object will be returned.
* If the result is a <code>Cartesian2</code>, <code>Cartesian3</code>, or <code>Cartesian4</code>,
* object will be returned. If the result is a <code>Cartesian2</code>, <code>Cartesian3</code>, or <code>Cartesian4</code>,
* a {@link Cartesian2}, {@link Cartesian3}, or {@link Cartesian4} object will be returned.
*
* @param {FrameState} frameState The frame state.
* @param {Cesium3DTileFeature} feature The feature who's properties may be used as variables in the expression.
* @returns {Boolean|Number|String|Color|Cartesian2|Cartesian3|Cartesian4|RegExp} The result of evaluating the expression.
* @returns {Boolean|Number|String|Cartesian2|Cartesian3|Cartesian4|RegExp} The result of evaluating the expression.
*/
Expression.prototype.evaluate = function(frameState, feature) {
ScratchStorage.reset();
var result = this._runtimeAst.evaluate(frameState, feature);
if ((result instanceof Color) || (result instanceof Cartesian2) || (result instanceof Cartesian3) || (result instanceof Cartesian4)) {
if ((result instanceof Cartesian2) || (result instanceof Cartesian3) || (result instanceof Cartesian4)) {
return result.clone();
}
return result;
Expand All @@ -212,7 +202,7 @@ define([
Expression.prototype.evaluateColor = function(frameState, feature, result) {
ScratchStorage.reset();
var color = this._runtimeAst.evaluate(frameState, feature);
return Color.clone(color, result);
return Color.fromCartesian4(color, result);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I figured evaluateColor should return a Color object. evaluate will just return a Cartesian4.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, agreed. It is fine for the Cesium implementation to map vec4 to Cesium's Color when we know it is the color property. This is an implementation detail and does not affect the spec.

};

/**
Expand Down Expand Up @@ -776,46 +766,46 @@ define([
};

Node.prototype._evaluateLiteralColor = function(frameState, feature) {
var result = ScratchStorage.getColor();
var color = scratchColor;
var args = this._left;
if (this._value === 'color') {
if (!defined(args)) {
return Color.fromBytes(255, 255, 255, 255, result);
Color.fromBytes(255, 255, 255, 255, color);
} else if (args.length > 1) {
Color.fromCssColorString(args[0].evaluate(frameState, feature), result);
result.alpha = args[1].evaluate(frameState, feature);
Color.fromCssColorString(args[0].evaluate(frameState, feature), color);
color.alpha = args[1].evaluate(frameState, feature);
} else {
Color.fromCssColorString(args[0].evaluate(frameState, feature), result);
Color.fromCssColorString(args[0].evaluate(frameState, feature), color);
}
} else if (this._value === 'rgb') {
Color.fromBytes(
args[0].evaluate(frameState, feature),
args[1].evaluate(frameState, feature),
args[2].evaluate(frameState, feature),
255, result);
255, color);
} else if (this._value === 'rgba') {
// convert between css alpha (0 to 1) and cesium alpha (0 to 255)
var a = args[3].evaluate(frameState, feature) * 255;
Color.fromBytes(
args[0].evaluate(frameState, feature),
args[1].evaluate(frameState, feature),
args[2].evaluate(frameState, feature),
a, result);
a, color);
} else if (this._value === 'hsl') {
Color.fromHsl(
args[0].evaluate(frameState, feature),
args[1].evaluate(frameState, feature),
args[2].evaluate(frameState, feature),
1.0, result);
1.0, color);
} else if (this._value === 'hsla') {
Color.fromHsl(
args[0].evaluate(frameState, feature),
args[1].evaluate(frameState, feature),
args[2].evaluate(frameState, feature),
args[3].evaluate(frameState, feature),
result);
color);
}
return result;
return Cartesian4.fromColor(color, ScratchStorage.getCartesian4());
};

Node.prototype._evaluateLiteralVector = function(frameState, feature) {
Expand Down Expand Up @@ -917,19 +907,18 @@ define([
}

var member = this._right.evaluate(frameState, feature);
if (property instanceof Color) {
// Color components may be accessed with .x, .y, .z, .w and implicitly with .red, .green, .blue, .alpha
if (member === 'x') {
return property.red;
} else if (member === 'y') {
return property.green;
} else if (member === 'z') {
return property.blue;
} else if (member === 'w') {
return property.alpha;
if ((property instanceof Cartesian2) || (property instanceof Cartesian3) || (property instanceof Cartesian4)) {
// Vector components may be accessed with .red, .green, .blue, .alpha and implicitly with .x, .y, .z, .w
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Like how glsl can access components of a vector with .r, .g, .b, .a, I kept in the .red, .green, .blue, .alpha. Should they be shortened to .r, etc instead, or should this be removed?

Copy link
Contributor

Choose a reason for hiding this comment

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

Let's keep it, but go with r, g, b, a. I went with the full words to start because I was copying the Cesium Color type, but we should stay consistent with GLSL so the styling language isn't too much of a hybrid.

Also, given that styles are often very concise and look like equations, this will fit well.

@pmconne this will be a small breaking change for your styles.

if (member === 'red') {
return property.x;
} else if (member === 'green') {
return property.y;
} else if (member === 'blue') {
return property.z;
} else if (member === 'alpha') {
return property.w;
}
}

return property[member];
};

Expand All @@ -943,27 +932,16 @@ define([
}

var member = this._right.evaluate(frameState, feature);
if (property instanceof Color) {
// Color components may be accessed with [0][1][2][3], ['x']['y']['z']['w'], and implicitly with ['red']['green']['blue']['alpha']
if (member === 0 || member === 'x') {
return property.red;
} else if (member === 1 || member === 'y') {
return property.green;
} else if (member === 2 || member === 'z') {
return property.blue;
} else if (member === 3 || member === 'w') {
return property.alpha;
}
} else if ((property instanceof Cartesian2) || (property instanceof Cartesian3) || (property instanceof Cartesian4)) {
// Vector components may be accessed with [0][1][2][3] and implicitly with ['x']['y']['z']['w']
if ((property instanceof Cartesian2) || (property instanceof Cartesian3) || (property instanceof Cartesian4)) {
// Vector components may be accessed with [0][1][2][3], ['red']['green']['blue']['alpha'] and implicitly with ['x']['y']['z']['w']
// For Cartesian2 and Cartesian3 out-of-range components will just return undefined
if (member === 0) {
if (member === 0 || member === 'red') {
return property.x;
} else if (member === 1) {
} else if (member === 1 || member === 'green') {
return property.y;
} else if (member === 2) {
} else if (member === 2 || member === 'blue') {
return property.z;
} else if (member === 3) {
} else if (member === 3 || member === 'alpha') {
return property.w;
}
}
Expand Down Expand Up @@ -999,7 +977,7 @@ define([

Node.prototype._evaluatePositive = function(frameState, feature) {
var left = this._left.evaluate(frameState, feature);
if ((left instanceof Color) || (left instanceof Cartesian2) || (left instanceof Cartesian3) || (left instanceof Cartesian4)) {
if ((left instanceof Cartesian2) || (left instanceof Cartesian3) || (left instanceof Cartesian4)) {
return left;
}
return +left;
Expand Down Expand Up @@ -1076,9 +1054,7 @@ define([
Node.prototype._evaluatePlus = function(frameState, feature) {
var left = this._left.evaluate(frameState, feature);
var right = this._right.evaluate(frameState, feature);
if ((right instanceof Color) && (left instanceof Color)) {
return Color.add(left, right, ScratchStorage.getColor());
} else if ((right instanceof Cartesian2) && (left instanceof Cartesian2)) {
if ((right instanceof Cartesian2) && (left instanceof Cartesian2)) {
return Cartesian2.add(left, right, ScratchStorage.getCartesian2());
} else if ((right instanceof Cartesian3) && (left instanceof Cartesian3)) {
return Cartesian3.add(left, right, ScratchStorage.getCartesian3());
Expand All @@ -1091,9 +1067,7 @@ define([
Node.prototype._evaluateMinus = function(frameState, feature) {
var left = this._left.evaluate(frameState, feature);
var right = this._right.evaluate(frameState, feature);
if ((right instanceof Color) && (left instanceof Color)) {
return Color.subtract(left, right, ScratchStorage.getColor());
} else if ((right instanceof Cartesian2) && (left instanceof Cartesian2)) {
if ((right instanceof Cartesian2) && (left instanceof Cartesian2)) {
return Cartesian2.subtract(left, right, ScratchStorage.getCartesian2());
} else if ((right instanceof Cartesian3) && (left instanceof Cartesian3)) {
return Cartesian3.subtract(left, right, ScratchStorage.getCartesian3());
Expand All @@ -1106,13 +1080,7 @@ define([
Node.prototype._evaluateTimes = function(frameState, feature) {
var left = this._left.evaluate(frameState, feature);
var right = this._right.evaluate(frameState, feature);
if ((right instanceof Color) && (left instanceof Color)) {
return Color.multiply(left, right, ScratchStorage.getColor());
} else if ((right instanceof Color) && (typeof(left) === 'number')) {
return Color.multiplyByScalar(right, left, ScratchStorage.getColor());
} else if ((left instanceof Color) && (typeof(right) === 'number')) {
return Color.multiplyByScalar(left, right, ScratchStorage.getColor());
} else if ((right instanceof Cartesian2) && (left instanceof Cartesian2)) {
if ((right instanceof Cartesian2) && (left instanceof Cartesian2)) {
return Cartesian2.multiplyComponents(left, right, ScratchStorage.getCartesian2());
} else if ((right instanceof Cartesian2) && (typeof(left) === 'number')) {
return Cartesian2.multiplyByScalar(right, left, ScratchStorage.getCartesian2());
Expand All @@ -1137,11 +1105,7 @@ define([
Node.prototype._evaluateDivide = function(frameState, feature) {
var left = this._left.evaluate(frameState, feature);
var right = this._right.evaluate(frameState, feature);
if ((right instanceof Color) && (left instanceof Color)) {
return Color.divide(left, right, ScratchStorage.getColor());
} else if ((left instanceof Color) && (typeof(right) === 'number')) {
return Color.divideByScalar(left, right, ScratchStorage.getColor());
} else if ((right instanceof Cartesian2) && (left instanceof Cartesian2)) {
if ((right instanceof Cartesian2) && (left instanceof Cartesian2)) {
return Cartesian2.divideComponents(left, right, ScratchStorage.getCartesian2());
} else if ((left instanceof Cartesian2) && (typeof(right) === 'number')) {
return Cartesian2.divideByScalar(left, right, ScratchStorage.getCartesian2());
Expand All @@ -1160,9 +1124,7 @@ define([
Node.prototype._evaluateMod = function(frameState, feature) {
var left = this._left.evaluate(frameState, feature);
var right = this._right.evaluate(frameState, feature);
if ((right instanceof Color) && (left instanceof Color)) {
return Color.mod(left, right, ScratchStorage.getColor());
} else if ((right instanceof Cartesian2) && (left instanceof Cartesian2)) {
if ((right instanceof Cartesian2) && (left instanceof Cartesian2)) {
return Cartesian2.fromElements(left.x % right.x, left.y % right.y, ScratchStorage.getCartesian2());
} else if ((right instanceof Cartesian3) && (left instanceof Cartesian3)) {
return Cartesian3.fromElements(left.x % right.x, left.y % right.y, left.z % right.z, ScratchStorage.getCartesian3());
Expand All @@ -1175,8 +1137,7 @@ define([
Node.prototype._evaluateEqualsStrict = function(frameState, feature) {
var left = this._left.evaluate(frameState, feature);
var right = this._right.evaluate(frameState, feature);
if ((right instanceof Color) && (left instanceof Color) ||
(right instanceof Cartesian2) && (left instanceof Cartesian2) ||
if ((right instanceof Cartesian2) && (left instanceof Cartesian2) ||
(right instanceof Cartesian3) && (left instanceof Cartesian3) ||
(right instanceof Cartesian4) && (left instanceof Cartesian4)) {
return left.equals(right);
Expand All @@ -1187,8 +1148,7 @@ define([
Node.prototype._evaluateEquals = function(frameState, feature) {
var left = this._left.evaluate(frameState, feature);
var right = this._right.evaluate(frameState, feature);
if ((right instanceof Color) && (left instanceof Color) ||
(right instanceof Cartesian2) && (left instanceof Cartesian2) ||
if ((right instanceof Cartesian2) && (left instanceof Cartesian2) ||
(right instanceof Cartesian3) && (left instanceof Cartesian3) ||
(right instanceof Cartesian4) && (left instanceof Cartesian4)) {
return left.equals(right);
Expand All @@ -1202,8 +1162,7 @@ define([
Node.prototype._evaluateNotEqualsStrict = function(frameState, feature) {
var left = this._left.evaluate(frameState, feature);
var right = this._right.evaluate(frameState, feature);
if ((right instanceof Color) && (left instanceof Color) ||
(right instanceof Cartesian2) && (left instanceof Cartesian2) ||
if ((right instanceof Cartesian2) && (left instanceof Cartesian2) ||
(right instanceof Cartesian3) && (left instanceof Cartesian3) ||
(right instanceof Cartesian4) && (left instanceof Cartesian4)) {
return !left.equals(right);
Expand All @@ -1214,8 +1173,7 @@ define([
Node.prototype._evaluateNotEquals = function(frameState, feature) {
var left = this._left.evaluate(frameState, feature);
var right = this._right.evaluate(frameState, feature);
if ((right instanceof Color) && (left instanceof Color) ||
(right instanceof Cartesian2) && (left instanceof Cartesian2) ||
if ((right instanceof Cartesian2) && (left instanceof Cartesian2) ||
(right instanceof Cartesian3) && (left instanceof Cartesian3) ||
(right instanceof Cartesian4) && (left instanceof Cartesian4)) {
return !left.equals(right);
Expand Down Expand Up @@ -1321,7 +1279,7 @@ define([

Node.prototype._evaluateToString = function(frameState, feature) {
var left = this._left.evaluate(frameState, feature);
if ((left instanceof RegExp) || (left instanceof Color) || (left instanceof Cartesian2) || (left instanceof Cartesian3) || (left instanceof Cartesian4)) {
if ((left instanceof RegExp) || (left instanceof Cartesian2) || (left instanceof Cartesian3) || (left instanceof Cartesian4)) {
return String(left);
}
//>>includeStart('debug', pragmas.debug);
Expand Down
Loading