diff --git a/.eslintignore b/.eslintignore index 4a4753f137..e35cabbe24 100755 --- a/.eslintignore +++ b/.eslintignore @@ -8,5 +8,9 @@ node_modules/ demos/assets/ demos/index.html demos/* +<<<<<<< HEAD rollup/* webpack/* +======= +src/core/three.js +>>>>>>> master diff --git a/.torch.compile.opts.js b/.torch.compile.opts.js index c2e828ddc9..142e0804d2 100755 --- a/.torch.compile.opts.js +++ b/.torch.compile.opts.js @@ -1,15 +1,15 @@ const path = require('path'); - module.exports = { babelrc: { presets: [ "@babel/preset-env" - ] + ], }, extensions: ['.js'], include: [ 'src/**/*.js', 'test/**/*.js', + 'node_modules/_three@0.101.1@three/**/*.js', 'node_modules/three/**/*.js', 'node_modules/simple-statistics/src/*.js' ], diff --git a/demos/hexgon.html b/demos/hexgon.html new file mode 100644 index 0000000000..ce5ed92af9 --- /dev/null +++ b/demos/hexgon.html @@ -0,0 +1,76 @@ + + + + + + + + + point_circle + + + + +
+ + + + + + + + diff --git a/package.json b/package.json index 01f457cb7e..c28b5a396a 100755 --- a/package.json +++ b/package.json @@ -78,11 +78,11 @@ "prepublishOnly": "npm run build-lib && npm run dist", "screenshot": "node ./bin/screenshot.js", "start": "npm run dev", - "test": "torch --compile --renderer --recursive test/unit", + "test": "torch --compile-opts ./.torch.compile.opts.js --compile --renderer --recursive test/unit", "test-all": "npm run test && npm run test-bugs", "test-bugs": "torch --compile --renderer --recursive test/bugs", "test-bugs-live": "torch --compile --interactive --watch --recursive test/bugs", - "test-live": "torch --compile --interactive --watch --recursive test/unit", + "test-live": "torch --compile --interactive --watch --recursive test/unit", "watch": "webpack --config webpack-dev.config.js", "win-dev": "node ./bin/win-dev.js" }, @@ -109,7 +109,7 @@ "polyline-normals": "^2.0.2", "rbush": "^2.0.2", "simple-statistics": "^7.0.1", - "three": "^0.96.0", + "three": "^0.101.1", "venn.js": "^0.2.20", "viewport-mercator-project": "^5.2.0", "webworkify-webpack": "^2.1.3", diff --git a/src/core/three.js b/src/core/three.js index f9db373473..7b344e2b23 100644 --- a/src/core/three.js +++ b/src/core/three.js @@ -35,4 +35,4 @@ export { BufferAttribute } from 'three/src/core/BufferAttribute.js'; -// export * from '../../build/Three.js'; +// export * from '../../build/three.js'; diff --git a/src/geom/buffer/heatmap/hexagon.js b/src/geom/buffer/heatmap/hexagon.js new file mode 100644 index 0000000000..eb95ef5d5b --- /dev/null +++ b/src/geom/buffer/heatmap/hexagon.js @@ -0,0 +1,31 @@ +import { fill } from '../../shape/polygon'; +export default function hexagonBuffer(layerData) { + const attribute = { + vertices: [], + miter: [], + colors: [], + pickingIds: [] + }; + const a = Math.cos(Math.PI / 6); + const points = [ + [ 0, -1, 0 ], + [ -a, -0.5, 0 ], + [ -a, 0.5, 0 ], + [ 0, 1, 0 ], + [ a, 0.5, 0 ], + [ a, -0.5, 0 ], + [ 0, -1, 0 ] + ]; + // const hexgonPoints = polygonPath(6); + const hexgonFill = fill([ points ]); + const { positionsIndex, positions } = hexgonFill; + layerData.forEach(element => { + positionsIndex.forEach(pointIndex => { + attribute.vertices.push(...element.coordinates); + attribute.miter.push(positions[pointIndex][0], positions[pointIndex][1]); + attribute.pickingIds.push(element.id); + attribute.colors.push(...element.color); + }); + }); + return attribute; +} diff --git a/src/geom/material/hexagon.js b/src/geom/material/hexagon.js new file mode 100644 index 0000000000..4b2e0896c8 --- /dev/null +++ b/src/geom/material/hexagon.js @@ -0,0 +1,31 @@ +import grid_frag from '../shader/hexagon_frag.glsl'; +import grid_vert from '../shader/hexagon_vert.glsl'; +import Material from './material'; + + +export default class hexagonMaterial extends Material { + getDefaultParameters() { + return { + uniforms: { + u_opacity: { value: 1.0 }, + u_time: { value: 0 }, + u_radius: { value: 0.01 }, + u_angle: { value: 0.01 }, + u_coverage: { value: 0.8 } + }, + defines: { + + } + }; + } + constructor(_uniforms, _defines, parameters) { + super(parameters); + const { uniforms, defines } = this.getDefaultParameters(); + this.uniforms = Object.assign(uniforms, this.setUniform(_uniforms)); + this.type = 'hexagonMaterial'; + this.defines = Object.assign(defines, _defines); + this.vertexShader = grid_vert; + this.fragmentShader = grid_frag; + this.transparent = true; + } +} diff --git a/src/geom/shader/hexagon_frag.glsl b/src/geom/shader/hexagon_frag.glsl new file mode 100644 index 0000000000..042dde511e --- /dev/null +++ b/src/geom/shader/hexagon_frag.glsl @@ -0,0 +1,8 @@ + precision highp float; + uniform float u_opacity; + varying vec4 v_color; + void main() { + vec4 color = v_color; + gl_FragColor = color; + gl_FragColor.a =color.a*u_opacity; +} \ No newline at end of file diff --git a/src/geom/shader/hexagon_vert.glsl b/src/geom/shader/hexagon_vert.glsl new file mode 100644 index 0000000000..30268d4861 --- /dev/null +++ b/src/geom/shader/hexagon_vert.glsl @@ -0,0 +1,17 @@ +precision highp float; +attribute vec2 miter; +attribute vec4 a_color; +uniform float u_radius; +uniform float u_coverage; +uniform float u_angle; +varying vec4 v_color; + +void main() { + mat4 matModelViewProjection = projectionMatrix * modelViewMatrix; + mat2 rotationMatrix = mat2(cos(u_angle), sin(u_angle), -sin(u_angle), cos(u_angle)); + v_color = a_color; + vec2 offset =vec2(rotationMatrix * miter * u_radius * u_coverage ); + float x = position.x + offset.x; + float y = position.y + offset.y; + gl_Position = matModelViewProjection * vec4(x, y, position.z, 1.0); +} \ No newline at end of file diff --git a/src/geom/shader/point_vert.glsl b/src/geom/shader/point_vert.glsl index 55b7d76a76..a39283badf 100644 --- a/src/geom/shader/point_vert.glsl +++ b/src/geom/shader/point_vert.glsl @@ -2,7 +2,6 @@ precision highp float; attribute vec4 a_color; attribute float a_size; attribute float a_shape; -attribute vec4 a_idColor; uniform vec4 u_stroke; uniform float u_strokeWidth; uniform float u_opacity; diff --git a/src/geom/shader/polygon_vert.glsl b/src/geom/shader/polygon_vert.glsl index eba0b62d02..5ae3a3c2a1 100644 --- a/src/geom/shader/polygon_vert.glsl +++ b/src/geom/shader/polygon_vert.glsl @@ -3,7 +3,6 @@ precision highp float; #define diffuseRatio 0.4 #define specularRatio 0.1 attribute vec4 a_color; -attribute vec4 a_idColor; attribute vec2 faceUv; attribute vec3 a_shape; attribute vec3 a_size; diff --git a/src/layer/heatmap.js b/src/layer/heatmap.js index f9971a55da..73b9b0b1b7 100644 --- a/src/layer/heatmap.js +++ b/src/layer/heatmap.js @@ -1,6 +1,8 @@ import Layer from '../core/layer'; import gridBuffer from '../geom/buffer/heatmap/grid'; import DrawGrid from './render/heatmap/gird'; +import DrawHexagon from './render/heatmap/hexagon'; +import hexagonBuffer from '../geom/buffer/heatmap/hexagon'; export default class HeatMapLayer extends Layer { shape(type) { @@ -13,6 +15,29 @@ export default class HeatMapLayer extends Layer { } _prepareRender() { this.init(); + switch (this.shapeType) { + case 'grid' : + this._drawGrid(); + break; + case 'hexagon' : + this._drawHexagon(); + break; + default: + this._drawGrid(); + } + } + _drawHexagon() { + const style = this.get('styleOptions'); + const { radius } = this.layerSource.data; + this._buffer = new hexagonBuffer(this.layerData); + const config = { + ...style, + radius + }; + const Mesh = new DrawHexagon(this._buffer, config); + this.add(Mesh); + } + _drawGrid() { this.type = 'heatmap'; const style = this.get('styleOptions'); const { xOffset, yOffset } = this.layerSource.data; @@ -25,4 +50,5 @@ export default class HeatMapLayer extends Layer { const girdMesh = new DrawGrid(this._buffer, config); this.add(girdMesh); } + } diff --git a/src/layer/render/heatmap/hexagon.js b/src/layer/render/heatmap/hexagon.js new file mode 100644 index 0000000000..04b7580cbd --- /dev/null +++ b/src/layer/render/heatmap/hexagon.js @@ -0,0 +1,21 @@ +import * as THREE from '../../../core/three'; +import GridMaterial from '../../../geom/material/hexagon'; +export default function DrawHexagon(attributes, style) { + const { opacity, radius, angle, coverage } = style; + const geometry = new THREE.BufferGeometry(); + geometry.addAttribute('position', new THREE.Float32BufferAttribute(attributes.vertices, 3)); + geometry.addAttribute('miter', new THREE.Float32BufferAttribute(attributes.miter, 2)); + geometry.addAttribute('a_color', new THREE.Float32BufferAttribute(attributes.colors, 4)); + geometry.addAttribute('pickingId', new THREE.Float32BufferAttribute(attributes.pickingIds, 1)); + const material = new GridMaterial({ + u_opacity: opacity, + u_radius: radius, + u_angle: angle / 180 * Math.PI, + u_coverage: coverage + }, { + SHAPE: false + }); + const hexgonMesh = new THREE.Mesh(geometry, material); + return hexgonMesh; +} + diff --git a/src/source/index.js b/src/source/index.js index ff88ba484e..1d7fe62ba4 100644 --- a/src/source/index.js +++ b/src/source/index.js @@ -8,6 +8,7 @@ import raster from './parser/raster'; import { registerTransform, registerParser } from './factory'; import { aggregatorToGrid } from './transform/grid'; +import { pointToHexbin } from './transform/hexagon'; import { map } from './transform/map'; registerParser('geojson', geojson); @@ -18,6 +19,7 @@ registerParser('raster', raster); // 注册transform registerTransform('grid', aggregatorToGrid); +registerTransform('hexagon', pointToHexbin); registerTransform('map', map); export { getTransform, registerTransform, getParser, registerParser } from './factory'; diff --git a/src/source/transform/grid.js b/src/source/transform/grid.js index d9c94ee54e..4098f15e15 100644 --- a/src/source/transform/grid.js +++ b/src/source/transform/grid.js @@ -11,8 +11,8 @@ export function aggregatorToGrid(data, option) { const { gridHash, gridOffset } = _pointsGridHash(dataArray, size); const layerData = _getGridLayerDataFromGridHash(gridHash, gridOffset, option); return { - xOffset: gridOffset.xOffset / 360 * (256 << 20) / 2, yOffset: gridOffset.xOffset / 360 * (256 << 20) / 2, + xOffset: gridOffset.xOffset / 360 * (256 << 20) / 2, dataArray: layerData }; } diff --git a/src/source/transform/hexagon.js b/src/source/transform/hexagon.js index f0aa9692f1..c550dc32ac 100644 --- a/src/source/transform/hexagon.js +++ b/src/source/transform/hexagon.js @@ -20,7 +20,7 @@ export function pointToHexbin(data, option) { .y(d => d.coordinates[1]); const hexbinBins = newHexbin(screenPoints); const result = { - size: pixlSize + radius: pixlSize }; result.dataArray = hexbinBins.map((hex, index) => { if (option.field && option.method) { @@ -31,8 +31,9 @@ export function pointToHexbin(data, option) { item[option.method] = hex[option.method]; return { ...item, + count: hex.length, coordinates: unProjectFlat([ hex.x, hex.y ]), - id: index + 1 + _id: index + 1 }; }); return result; diff --git a/test/unit/geom/buffer/heatmap/hexagon.js b/test/unit/geom/buffer/heatmap/hexagon.js new file mode 100644 index 0000000000..c92074bca3 --- /dev/null +++ b/test/unit/geom/buffer/heatmap/hexagon.js @@ -0,0 +1,35 @@ +import { expect } from 'chai'; +import hexagonBuffer from '../../../../../src/geom/buffer/heatmap/hexagon'; +describe('hexagon heatMap buffer', () => { + const layerData = [ + { color: [ 1, 1, 0, 1 ], coordinates: [ 120.12063099925889, 30.263947783103486, 0 ], id: 1 }, + { color: [ 1, 0.5, 0, 1 ], coordinates: [ 120.12218696039365, 30.263947783103486, 0 ], id: 2 }, + { + color: [ 1, 0.1, 0, 1 ], + coordinates: [ 120.12374292152843, 30.263947783103486, 0 ], + id: 3 + }, + { color: [ 1, 0, 0.2, 1 ], coordinates: [ 120.1252988826632, 30.263947783103486, 0 ], id: 4 }, + { + color: [ 0, 1, 0, 1 ], + coordinates: [ 120.12607686323062, 30.263947783103486, 0 ], + id: 5 + }, + { + color: [ 1, 1, 0, 1 ], + coordinates: [ 120.12685484379799, 30.263947783103486, 0 ], + id: 6 + }, + { color: [ 1, 1, 1, 1 ], coordinates: [ 120.12841080493274, 30.263947783103486, 0 ], id: 7 }, + { color: [ 0, 1, 1, 1 ], coordinates: [ 120.13230070776972, 30.263947783103486, 0 ], id: 8 }, + { color: [ 0, 1, 0, 1 ], coordinates: [ 120.12763282436538, 30.263947783103486, 0 ], id: 9 }, + { color: [ 1, 1, 0, 1 ], coordinates: [ 120.12996676606754, 30.263947783103486, 0 ], id: 10 } + ]; + it('hexagon buffer', () => { + const attribute = hexagonBuffer(layerData); + expect(attribute.colors.length).eql(480); + expect(attribute.miter.length).eql(240); + expect(attribute.pickingIds.length).eql(120); + expect(attribute.vertices.length).eql(360); + }); +}); diff --git a/test/unit/shader-module/base-spec.js b/test/unit/shader-module/base-spec.js index 8f2b35c079..ebe8cd9b43 100644 --- a/test/unit/shader-module/base-spec.js +++ b/test/unit/shader-module/base-spec.js @@ -24,9 +24,8 @@ describe('test shader module', function() { it('should import a module correctly.', function() { const { vs, fs } = getModule('module1'); - expect(vs).eq('#define PI 3.14'); - expect(fs).eq(''); + expect(fs.replace(/(\s+)|(\n)+|(\r\n)+/g, '')).eqls('#ifdefGL_FRAGMENT_PRECISION_HIGHprecisionhighpfloat;#elseprecisionmediumpfloat;#endif'); }); }); diff --git a/webpack.config.js b/webpack.config.js index 9106df5d7f..823d9ef161 100755 --- a/webpack.config.js +++ b/webpack.config.js @@ -4,7 +4,8 @@ const pkg = require('./package.json'); module.exports = { devtool: 'cheap-source-map', entry: { - l7: './src/index.js' + l7: './src/index.js', + three: './src/core/three.js' }, output: { filename: '[name].js',