Skip to content

Commit

Permalink
update docs (#388)
Browse files Browse the repository at this point in the history
  • Loading branch information
Pessimistress committed Sep 9, 2019
1 parent 6941e82 commit 310e97e
Show file tree
Hide file tree
Showing 8 changed files with 391 additions and 6 deletions.
1 change: 1 addition & 0 deletions modules/layers/src/index.js
Expand Up @@ -21,3 +21,4 @@
export {default as SignLayer} from './sign-layer/sign-layer';
export {default as TrafficLightLayer} from './traffic-light-layer/traffic-light-layer';
export {default as ImageryLayer} from './imagery-layer/imagery-layer';
export {default as LaneLayer} from './lane-layer/lane-layer';
96 changes: 96 additions & 0 deletions modules/layers/src/lane-layer/README.md
@@ -0,0 +1,96 @@
# LaneLayer

The LaneLayer renders enhanced paths that can be used as lane markers.

```js
import {LogViewer} from 'streetscape.gl';
import {LaneLayer} from '@streetscape.gl/layers';

/**
* Data format:
* [
* {
* path: [[-122.450, 37.789, 0], [-122,451, 37.792, 0], ...],
* color: ['yellow', 'white'],
* dashed: [false, true]
* },
* {
* path: [[-122.450, 37.789, 0], [-122,451, 37.792, 0], ...],
* color: ['white'],
* dashed: [true]
* }
* ...
* ]
*/
const COLORS = {
yellow: [255, 255, 0],
white: [255, 255, 255],
none: [0, 0, 0, 0]
};

const layer = new LaneLayer({
id: 'lane-layer',
data,
getPath: d => d.path,
getWidth: d => d.color.length > 1 ? [0.05, 0.08, 0.05] : [0.05],
getColor: d => COLORS[d.color[0]],
getColor2: d => COLORS[d.color[1]] || COLORS.NONE,
getDashArray: d => d.dashed[0] ? [4, 2] : [0, 0]
getDashArray2: d => d.dashed[1] ? [4, 2] : [0, 0]
});

return (<LogViewer ... customLayers={[layer]} />);
```

## Properties

Inherits from all
[PathLayer](https://deck.gl/#/documentation/deckgl-api-reference/layers/path-layer) properties.

### Render Options

##### `highPrecisionDash` (Boolean, optional)

- Default: `false`

If `true`, generate more consistent dashes by stacking them from the beginning of the path. If
`false`, dashes are stacked from the beginning of the segment. Has an one-time performance overhead
when processing path data on the CPU.

### Data Accessors

##### `getWidth` (Function|Array, optional)

- Default: `[1]`

Returns the width of the path in an array: `[leftStroke, gap, rightStroke]`, in units specified by
`widthUnits` (default meters). `gap` and `rightStroke` default to `0` if omitted.

For example, drawing a 1m wide path using double lines with a 20% gap: `[0.4, 0.2, 0.4]`. Offsetting
a 1m wide path to the left by 1m: `[1, 2]`.

##### `getColor` (Function|Array, optional)

- Default: `[0, 0, 0, 255]`

The rgba color of the left stroke, in `r, g, b, [a]`. Each component is in the 0-255 range.

##### `getColor2` (Function|Array, optional)

- Default: `[0, 0, 0, 255]`

The rgba color of the right stroke, in `r, g, b, [a]`. Each component is in the 0-255 range.

##### `getDashArray` (Function|Array, optional)

- Default: `null`

The dash array to draw the left stroke with: `[dashSize, gapSize, dashSize, gapSize]` relative to
the width of the path.

##### `getDashArray2` (Function|Array, optional)

- Default: `null`

The dash array to draw the right stroke with: `[dashSize, gapSize, dashSize, gapSize]` relative to
the width of the path.
208 changes: 208 additions & 0 deletions modules/layers/src/lane-layer/lane-layer.js
@@ -0,0 +1,208 @@
// Copyright (c) 2019 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

import {PathLayer} from '@deck.gl/layers';
import GL from '@luma.gl/constants';
import {Vector3} from 'math.gl';

const defaultProps = {
...PathLayer.defaultProps,

highPrecisionDash: false,

getColor2: {type: 'accessor', value: [0, 0, 0, 255]},
getWidth: {type: 'accessor', value: [1, 0, 0]},
getDashArray2: {type: 'accessor', value: [0, 0]}
};

export default class LaneLayer extends PathLayer {
getShaders() {
const shaders = super.getShaders();

shaders.vs = shaders.vs
.replace('attribute float instanceStrokeWidths', 'attribute vec3 instanceStrokeWidths')
.replace('attribute vec2 instanceDashArrays', 'attribute vec4 instanceDashArrays')
.replace('varying vec2 vDashArray', 'varying vec4 vDashArray')
.replace(
'instanceStrokeWidths * widthScale',
'(instanceStrokeWidths.x + instanceStrokeWidths.y + instanceStrokeWidths.z) * widthScale'
);

// TODO - move default dash array handling to an extension
shaders.fs = shaders.fs
.replace(
/bool dash_isFragInGap[\s\S]*?\n\}/,
`
bool dash_isFragInGap() {
float solid1 = vDashArray.x;
float gap1 = solid1 + vDashArray.y;
float solid2 = gap1 + vDashArray.z;
float unitLength = solid2 + vDashArray.w;
if (unitLength == 0.0 || vDashArray.y == 0.0) {
return false;
}
unitLength = mix(
unitLength,
vPathLength / round(vPathLength / unitLength),
alignMode
);
float offset = mix(vPathOffset, vDashArray.x / 2.0, alignMode);
float unitPosition = mod2(vPathPosition.y + offset, unitLength);
return unitPosition > solid1 && unitPosition < gap1 || unitPosition > solid2;
}
`
)
.replace('varying vec2 vDashArray', 'varying vec4 vDashArray');

shaders.inject = {
'vs:#decl': `
uniform float strokeIndex;
attribute float instanceStartRatio;
varying vec2 vWidth;
varying float vPathOffset;
`,
'fs:#decl': `
varying vec2 vWidth;
varying float vPathOffset;
`,
'vs:#main-end': `
float totalWidth = instanceStrokeWidths.x + instanceStrokeWidths.y + instanceStrokeWidths.z;
if (strokeIndex == 0.0) {
vWidth = vec2(0.0, instanceStrokeWidths.x / totalWidth);
} else {
vWidth = vec2(1.0 - instanceStrokeWidths.z / totalWidth, 1.0);
}
// map to [-1.0, 1.0] space
vWidth = vWidth * 2.0 - 1.0;
vPathOffset = vPathLength * instanceStartRatio;
`,
'fs:#main-start': `
if (vPathPosition.x < vWidth.x || vPathPosition.x > vWidth.y) {
discard;
}
`
};

return shaders;
}

initializeState(context) {
super.initializeState(context);

this.getAttributeManager().addInstanced({
instanceStrokeWidths: {
size: 3,
accessor: 'getWidth',
defaultValue: [1, 0, 0]
},
instanceColors2: {
size: this.props.colorFormat.length,
type: GL.UNSIGNED_BYTE,
normalized: true,
accessor: 'getColor2',
defaultValue: [0, 0, 0, 255]
},
instanceStartRatio: {
size: 1,
update: this.calculateStartRatios
},
instanceDashArrays: {size: 4, accessor: 'getDashArray'},
instanceDashArrays2: {size: 4, accessor: 'getDashArray2'}
});
}

draw(params) {
const {model} = this.state;
const attributes = this.getAttributeManager().getAttributes();
model.setUniforms({
strokeIndex: 0
});
model.setAttributes({
instanceColors: attributes.instanceColors,
instanceDashArrays: attributes.instanceDashArrays
});
super.draw(params);

model.setUniforms({
strokeIndex: 1
});
model.setAttributes({
instanceColors: attributes.instanceColors2,
instanceDashArrays: attributes.instanceDashArrays2
});
model.draw();
}

calculateStartRatios(attribute) {
if (!this.props.highPrecisionDash) {
attribute.constant = true;
attribute.value = new Float32Array(1);
return;
}

const {numInstances} = this.state;
const {viewport} = this.context;

let {startPositions, endPositions, instanceTypes} = this.getAttributeManager().getAttributes();
startPositions = startPositions.value;
endPositions = endPositions.value;
instanceTypes = instanceTypes.value;

const target = attribute.value;

const startPoint = new Vector3();
const endPoint = new Vector3();
let totalLength = 0;

for (let i = 0; i < numInstances; i++) {
startPoint.set(
startPositions[i * 3 + 3],
startPositions[i * 3 + 4],
startPositions[i * 3 + 5]
);

endPoint.set(
(endPoint[0] = endPositions[i * 3]),
(endPoint[1] = endPositions[i * 3 + 1]),
(endPoint[2] = endPositions[i * 3 + 2])
);

startPoint.copy(viewport.projectPosition(startPoint));
endPoint.copy(viewport.projectPosition(endPoint));

const segmentLength = startPoint.distance(endPoint);

target[i] = segmentLength ? totalLength / segmentLength : 0;

if (instanceTypes[i] <= 1) {
totalLength += segmentLength;
} else {
totalLength = 0;
}
}
}
}

LaneLayer.layerName = 'LaneLayer';
LaneLayer.defaultProps = defaultProps;
2 changes: 0 additions & 2 deletions modules/layers/src/sign-layer/README.md
Expand Up @@ -39,8 +39,6 @@ return (<LogViewer ... customLayers={[layer]} />);

## Properties

Inherits from all [Base Layer](/docs/api-reference/layer.md) properties.

### Render Options

##### `iconAtlas` (Texture2D | String, required)
Expand Down
Expand Up @@ -61,8 +61,7 @@ const defaultProps = {

export default class TrafficLightLayer extends Layer {
getShaders() {
const projectModule = this.use64bitProjection() ? 'project64' : 'project32';
return {vs, fs, modules: [projectModule, 'gouraud-lighting', 'picking']};
return {vs, fs, modules: ['project32', 'gouraud-lighting', 'picking']};
}

initializeState() {
Expand Down
37 changes: 36 additions & 1 deletion test/apps/layers/src/custom-layers.js
Expand Up @@ -17,7 +17,7 @@
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
import {SignLayer, TrafficLightLayer, ImageryLayer} from '@streetscape.gl/layers';
import {SignLayer, TrafficLightLayer, ImageryLayer, LaneLayer} from '@streetscape.gl/layers';

const signLayerProps = {
coordinate: 'VEHICLE_RELATIVE',
Expand Down Expand Up @@ -80,5 +80,40 @@ export default [
uCount: 2,
vCount: 2,
transparentColor: [255, 255, 255, 0]
}),

new LaneLayer({
id: 'lanes',
coordinate: 'VEHICLE_RELATIVE',

data: [
{
path: [
[0, 0, 0],
[2, 1, 0],
[3, 3, 0],
[3.05, 3, 0],
[3.05, 3.05, 0],
[3.1, 3.05, 0],
[3.1, 3.1, 0],
[3.15, 3.1, 0],
[3.15, 3.15, 0],
[3.2, 3.15, 0],
[3.2, 3.2, 0],
[5, 4, 0],
[7, 2.4, 0],
[7, 0, 0],
[10, 0, 0]
]
}
],

highPrecisionDash: true,

getPath: d => d.path,
getColor: [80, 200, 0],
getColor2: [0, 128, 255],
getWidth: [0.1, 0.05, 0.1],
getDashArray: [4, 1, 1, 1]
})
];
Binary file added test/render/golden-images/lanes.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 310e97e

Please sign in to comment.