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

Vector types: vec2, vec3, vec4 #166

Merged
merged 4 commits into from
Jan 16, 2017
Merged
Changes from 1 commit
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
77 changes: 74 additions & 3 deletions Styling/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Example: Creating a color ramp based on building height.
* Gabby Getz, [@ggetz](https://github.com/ggetz)
* Matt Amato, [@matt_amato](https://twitter.com/matt_amato)
* Tom Fili, [@CesiumFili](https://twitter.com/CesiumFili)
* Sean Lilley, [@lilleyse](https://github.com/lilleyse)
* Patrick Cozzi, [@pjcozzi](https://twitter.com/pjcozzi)


Expand All @@ -37,6 +38,9 @@ Contents:
* [Types](#types)
* [Number](#number)
* [Color](#color)
* [vec2](#vector)
* [vec3](#vector)
* [vec4](#vector)
* [RegExp](#regexp)
* [Conversions](#conversions)
* [Variables](#variables)
Expand Down Expand Up @@ -170,7 +174,7 @@ Also, see the [JSON schema](schema).

## Expressions

The language for expressions is a small subset of JavaScript ([EMCAScript 5](http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf)), plus native color and regular expression types and access to tileset feature properties in the form of readonly variables.
The language for expressions is a small subset of JavaScript ([EMCAScript 5](http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf)), plus native color, vector, and regular expression types and access to tileset feature properties in the form of readonly variables.

_Implementation tip: Cesium uses the [jsep](http://jsep.from.so/) JavaScript expression parser library to parse style expressions._

Expand Down Expand Up @@ -207,9 +211,12 @@ The following types are supported:
* `Number`
* `String`
* `Color`
* `vec2`
* `vec3`
* `vec4`
* `RegExp`

All of the types except `Color` and `RegExp` have the same syntax and runtime behavior as JavaScript. `Color` is derived from [CSS3 Colors](https://www.w3.org/TR/css3-color/) and behaves similarly to a JavaScript `Object` (see the [Color section](#color)). `RegExp` is derived from JavaScript and described in the [RegExp section](#regexp).
All of the types except `Color`, `vec2`, `vec3`, `vec4`, and `RegExp` have the same syntax and runtime behavior as JavaScript. `Color` is derived from [CSS3 Colors](https://www.w3.org/TR/css3-color/) and behaves similarly to a JavaScript `Object` (see the [Color section](#color)). `vec2`, `vec3`, and `vec4` are derived from GLSL vectors and behave similarly to JavaScript `Object` (see the [Vector section](#vector)). `RegExp` is derived from JavaScript and described in the [RegExp section](#regexp).

Example expressions for different types include the following:
* `true`, `false`
Expand All @@ -218,6 +225,9 @@ Example expressions for different types include the following:
* `1.0`, `NaN`, `Infinity`
* `'Cesium'`, `"Cesium"`
* `color('#00FFFF')`
* `vec2(1.0, 2.0)`
* `vec3(1.0, 2.0, 3.0)`
* `vec4(1.0, 2.0, 3.0, 4.0)`
* `regExp('^Chest'))`

Explicit conversions between primitive types are handled with `Boolean`, `Number`, and `String` functions.
Expand Down Expand Up @@ -281,13 +291,66 @@ Colors store rgba components internally, where each component is in the range `0

For example: `color.red`.

Color components may also be accessed with `.x`, `.y`, `.z`, `.w` and `[0]`, `[1]`, `[2]`, `[3]`.

Colors support the following binary operators by performing component-wise operations: `===`, `==`, `!==`, `!=`, `+`, `-`, `*`, `/`, and `%`. For example `color() === color()` is true since the red, green, blue, and alpha components are equal. This is not the same behavior as a JavaScript `Object`, where, for example, reference equality would be used. Operators are essentially overloaded for `Color`.

Colors have a `toString` function for explicit (and implicit) conversion to strings in the format `'(red, green, blue, alpha)'`.
* `toString() : String`

Colors do not expose any other functions or a `prototype` object.

#### Vector

The styling language includes 2, 3, and 4 component floating-point vector types: `vec2`, `vec3`, and `vec4`. Vector constructors share the same rules as GLSL:

##### vec2

* `vec2(Number)` - initialize each component with the number
* `vec2(Number, Number)` - initialize with two numbers
* `vec2(vec2)` - initialize with another `vec2`
* `vec2(vec3)` - drops the third component of a `vec3`
* `vec2(vec4)` - drops the third and fourth component of a `vec4`

##### vec3

* `vec3(Number)` - initialize each component with the number
* `vec3(Number, Number, Number)` - initialize with three numbers
* `vec3(vec3)` - initialize with another `vec3`
* `vec3(vec4)` - drops the fourth component of a `vec4`
* `vec3(vec2, Number)` - initialize with a `vec2` and number
* `vec3(Number, vec2)` - initialize with a `vec2` and number

##### vec4

* `vec4(Number)` - initialize each component with the number
* `vec4(Number, Number, Number, Number)` - initialize with four numbers
* `vec4(vec4)` - initialize with another `vec4`
* `vec4(vec2, Number, Number)` - initialize with a `vec2` and two numbers
* `vec4(Number, vec2, Number)` - initialize with a `vec2` and two numbers
* `vec4(Number, Number, vec2)` - initialize with a `vec2` and two numbers
* `vec4(vec3, Number)` - initialize with a `vec3` and number
* `vec4(Number, vec3)` - initialize with a `vec3` and number

`vec2` components may be accessed with `.x`, `.y` and `[0]`, `[1]`.
Copy link
Contributor

Choose a reason for hiding this comment

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

Looks like this is in the vec4 section. Either create a new section here or move some of these sentences to be in the right vector type section just above.


`vec3` components may be accessed with `.x`, `.y`, `.z` and `[0]`, `[1]`, `[2]`.

`vec4` components may be accessed with `.x`, `.y`, `.z`, `.w` and `[0]`, `[1]`, `[2]`, `[3]`.

Unlike GLSL, the styling language does not support swizzling. For example `vec3(1.0).xy` is not supported.

Vectors support the following unary operators: `-`, `+`.

Vectors support the following binary operators by performing component-wise operations: `===`, `==`, `!==`, `!=`, `+`, `-`, `*`, `/`, and `%`. For example `vec4(1.0) === vec4(1.0)` is true since the x, y, z, and w components are equal. This is not the same behavior as a JavaScript `Object`, where, for example, reference equality would be used. Operators are essentially overloaded for `vec2`, `vec3`, and `vec4`.

Operations between vectors of different types will not evaluate component-wise, but instead will evaluate as JavaScript objects. For example `vec2(1.0) === vec3(1.0)` is false and `vec2(1.0) * vec4(1.0)` is `NaN`. See the [Conversions](#conversions) section for more details.
Copy link
Contributor

Choose a reason for hiding this comment

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

This is awkward. Can we do better?

vec2(1.0) === vec3(1.0)

What does this do in GLSL? Based on the constructor overloads, is one converted to the other?

Instead of returning false/NaN for these examples, is it reasonable to implement if these are type mismatch errors?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

GLSL will not compile with that, you need to cast explicitly.

Equality checks could be made to work without too much trouble, the multiply would be harder (is the result vec2 or vec4?). Originally all this would work if vec2, vec3, and vec4 were treated as the same vec4 type, but I thought the point of moving away from that was to prevent expressions like these from working.

Copy link
Contributor

Choose a reason for hiding this comment

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

Right, is it reasonable to implement if these are type mismatch errors?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh I think I misunderstood your comment.

It shouldn't be hard to detect type mismatch errors in the JS backend, as usual it's more difficult in the GLSL backend, but still possible to just catch a shader failure and throw a generic type mismatch error (as talked about offline).

Copy link
Contributor

Choose a reason for hiding this comment

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

Great, let's go with the type mismatch.


`vec2`, `vec3`, and `vec4` have a `toString` function for explicit (and implicit) conversion to strings in the format `'(x, y)'`, `'(x, y, z)'`, and `'(x, y, z, w)'`.
* `toString() : String`

`vec2`, `vec3`, and `vec4` do not expose any other functions or a `prototype` object.

#### RegExp

Regular expressions are created with the following functions, which behave like the JavaScript [`RegExp`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp) constructor:
Expand Down Expand Up @@ -348,7 +411,7 @@ Regular expressions are treated as `NaN` when performing operations with operato

Style expressions follow JavaScript conversion rules.

For conversions involving `Color` or `RegExp`, they are treated as JavaScript objects. For example, `Color` implicitly converts to `NaN` with `==`, `!=`, `>`, `>=`, `<`, and `<=` operators. In Boolean expressions, a `Color` implicitly converts to `true`, e.g., `!!color() === true`. In string expressions, `Color` implicitly converts to `String` using its `toString` function.
For conversions involving `Color`, `vec2`, `vec3`, `vec4`, and `RegExp`, they are treated as JavaScript objects. For example, `Color` implicitly converts to `NaN` with `==`, `!=`, `>`, `>=`, `<`, and `<=` operators. In Boolean expressions, `Color`, `vec2`, `vec3`, and `vec4` implicitly convert to `true`, e.g., `!!color() === true`. In string expressions, `Color`, `vec2`, `vec3`, and `vec4` implicitly converts to `String` using their `toString` function.

### Variables

Expand Down Expand Up @@ -385,6 +448,14 @@ ${order} === 1
${name} === 'Feature name'
```

Additionally, variables originating from vector properties stored in the [Batch Table Binary](../TileFormats/BatchTable/README.md#binary-body) are treated as vector types:

| `componentType` | variable type |
| --- | --- |
| `"VEC2"` | `vec2` |
| `"VEC3"` | `vec3` |
| `"VEC4"` | `vec4` |

Variables can be used to construct colors, for example:
```
rgba(${red}, ${green}, ${blue}, ${alpha})
Expand Down