@deck.gl/experimental-layers
Version:
Experimental layers for deck.gl
153 lines (136 loc) • 4.74 kB
JavaScript
// Copyright (c) 2015 - 2017 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 {Layer} from '@deck.gl/core';
import GL from 'luma.gl/constants';
import {Model, Geometry, fp64} from 'luma.gl';
const {fp64LowPart} = fp64;
import vs from './bezier-curve-layer-vertex.glsl';
import fs from './bezier-curve-layer-fragment.glsl';
const NUM_SEGMENTS = 40;
const DEFAULT_COLOR = [0, 0, 0, 255];
const defaultProps = {
strokeWidth: {type: 'number', min: 0, value: 1},
fp64: false,
getSourcePosition: {type: 'accessor', value: x => x.sourcePosition},
getTargetPosition: {type: 'accessor', value: x => x.targetPosition},
getControlPoint: {type: 'accessor', value: x => x.controlPoint},
getColor: {type: 'accessor', value: DEFAULT_COLOR}
};
export default class BezierCurveLayer extends Layer {
getShaders() {
return {vs, fs, modules: ['picking']};
}
initializeState() {
const {attributeManager} = this.state;
/* eslint-disable max-len */
attributeManager.addInstanced({
instanceSourcePositions: {
size: 3,
transition: true,
accessor: 'getSourcePosition'
},
instanceTargetPositions: {
size: 3,
transition: true,
accessor: 'getTargetPosition'
},
instanceControlPoints: {
size: 3,
transition: false,
accessor: 'getControlPoint'
},
instanceColors: {
size: 4,
type: GL.UNSIGNED_BYTE,
transition: true,
accessor: 'getColor',
defaultValue: [0, 0, 0, 255]
}
});
/* eslint-enable max-len */
}
updateAttribute({props, oldProps, changeFlags}) {
if (props.fp64 !== oldProps.fp64) {
const {attributeManager} = this.state;
attributeManager.invalidateAll();
}
}
updateState({props, oldProps, changeFlags}) {
super.updateState({props, oldProps, changeFlags});
if (props.fp64 !== oldProps.fp64) {
const {gl} = this.context;
this.setState({model: this._getModel(gl)});
}
this.updateAttribute({props, oldProps, changeFlags});
}
draw({uniforms}) {
const {strokeWidth} = this.props;
this.state.model.render(
Object.assign({}, uniforms, {
strokeWidth
})
);
}
_getModel(gl) {
/*
* (0, -1)-------------_(1, -1)
* | _,-" |
* o _,-" o
* | _,-" |
* (0, 1)"-------------(1, 1)
*/
let positions = [];
for (let i = 0; i <= NUM_SEGMENTS; i++) {
positions = positions.concat([i, -1, 0, i, 1, 0]);
}
const model = new Model(
gl,
Object.assign({}, this.getShaders(), {
id: this.props.id,
geometry: new Geometry({
drawMode: GL.TRIANGLE_STRIP,
attributes: {
positions: new Float32Array(positions)
}
}),
isInstanced: true,
shaderCache: this.context.shaderCache
})
);
model.setUniforms({numSegments: NUM_SEGMENTS});
return model;
}
calculateInstanceSourceTargetPositions64xyLow(attribute) {
const {data, getSourcePosition, getTargetPosition} = this.props;
const {value, size} = attribute;
let i = 0;
data.forEach(object => {
const sourcePosition = getSourcePosition(object);
const targetPosition = getTargetPosition(object);
value[i + 0] = fp64LowPart(sourcePosition[0]);
value[i + 1] = fp64LowPart(sourcePosition[1]);
value[i + 2] = fp64LowPart(targetPosition[0]);
value[i + 3] = fp64LowPart(targetPosition[1]);
i += size;
});
}
}
BezierCurveLayer.layerName = 'BezierCurveLayer';
BezierCurveLayer.defaultProps = defaultProps;