From a942af8494046ce4935064e156913c4e65f1dc96 Mon Sep 17 00:00:00 2001 From: "wensen.lws" Date: Tue, 20 Nov 2018 17:49:45 +0800 Subject: [PATCH 1/5] chore(dev): fixing code style to pass linting --- src/core/layer.js | 17 ++++++++--------- src/core/scene.js | 7 ++++--- src/geom/buffer/point.js | 2 +- src/layer/pointLayer.js | 4 ++-- src/source/csvSource.js | 3 +-- src/source/geojsonSource.js | 22 ++++++++++------------ src/worker/main.worker.js | 3 +-- 7 files changed, 27 insertions(+), 31 deletions(-) diff --git a/src/core/layer.js b/src/core/layer.js index f8132f46b0..4a7e37b7db 100644 --- a/src/core/layer.js +++ b/src/core/layer.js @@ -419,9 +419,8 @@ export default class Layer extends Base { } } /** - * - * @param {*} overwrite - * @param {*} callback + * @param {*} type 类型 + * @param {*} callback 回调函数 */ on(type, callback) { @@ -448,7 +447,7 @@ export default class Layer extends Base { const pickmaterial = new PickingMaterial({ u_zoom: this.scene.getZoom() }); - + const pickingMesh = new THREE[mesh.type](mesh.geometry, pickmaterial); pickmaterial.setDefinesvalue(this.type, true); pickingMesh.onBeforeRender = () => { @@ -464,7 +463,7 @@ export default class Layer extends Base { // TODO: Find a way to properly remove this listener on destroy this.scene.on('pick', e => { // Re-emit click event from the layer - const { featureId, point2d, point3d, intersects } = e; + const { featureId, point2d, /* point3d, */intersects } = e; if (intersects.length === 0) { return; } const source = this.layerSource.get('data'); const feature = source.features[featureId]; @@ -493,7 +492,7 @@ export default class Layer extends Base { const colorAttr = this.layerMesh.geometry.attributes.a_color; const firstId = pickingId.indexOf(featureStyleId[0] + 1); for (let i = firstId; i < pickingId.length; i++) { - if (pickingId[i] == featureStyleId[0] + 1) { + if (pickingId[i] === featureStyleId[0] + 1) { colorAttr.array[i * 4 + 0] = color[0]; colorAttr.array[i * 4 + 1] = color[1]; colorAttr.array[i * 4 + 2] = color[2]; @@ -556,7 +555,7 @@ export default class Layer extends Base { } else if (this.type === 'polyline') { offset = 2; } - this._object3D.position.z = offset * Math.pow(2, 20 - zoom); + this._object3D.position.z = offset * Math.pow(2, 20 - zoom); if (zoom < minZoom || zoom > maxZoom) { this._object3D.visible = false; } else if (this.get('visible')) { @@ -569,11 +568,11 @@ export default class Layer extends Base { resetStyle() { const pickingId = this.layerMesh.geometry.attributes.pickingId.array; const colorAttr = this.layerMesh.geometry.attributes.a_color; - this._activeIds.forEach((index, value) => { + this._activeIds.forEach(index => { const color = this.StyleData[index].color; const firstId = pickingId.indexOf(index + 1); for (let i = firstId; i < pickingId.length; i++) { - if (pickingId[i] == index + 1) { + if (pickingId[i] === index + 1) { colorAttr.array[i * 4 + 0] = color[0]; colorAttr.array[i * 4 + 1] = color[1]; colorAttr.array[i * 4 + 2] = color[2]; diff --git a/src/core/scene.js b/src/core/scene.js index 52e9d90ed1..36b1a65430 100644 --- a/src/core/scene.js +++ b/src/core/scene.js @@ -33,9 +33,10 @@ export default class Scene extends Base { Map.on('mapLoad', () => { this._initEngine(Map.renderDom); const sceneMap = new GaodeMap(Map.map); - // eslint-disable-next-line - Object.getOwnPropertyNames(sceneMap.__proto__).forEach((key)=>{ - if ('key' !== 'constructor') { this.__proto__[key] = sceneMap.__proto__[key]; } + Object.getOwnPropertyNames(sceneMap.prototype).forEach(key => { + if (key !== 'constructor') { + this.prototype[key] = sceneMap.prototype[key]; + } }); this.map = Map.map; Map.asyncCamera(this._engine); diff --git a/src/geom/buffer/point.js b/src/geom/buffer/point.js index bb928c86af..833b101a2c 100644 --- a/src/geom/buffer/point.js +++ b/src/geom/buffer/point.js @@ -1,7 +1,7 @@ import BufferBase from './bufferBase'; import { regularShape } from '../shape/index'; import Util from '../../util'; -import * as THREE from '../../core/three'; +// import * as THREE from '../../core/three'; export default class PointBuffer extends BufferBase { geometryBuffer() { const type = this.get('type'); diff --git a/src/layer/pointLayer.js b/src/layer/pointLayer.js index 1ba952e088..fa9c1bc7bb 100644 --- a/src/layer/pointLayer.js +++ b/src/layer/pointLayer.js @@ -7,7 +7,7 @@ import TextBuffer from '../geom/buffer/text'; import TextMaterial from '../geom/material/textMaterial'; import radar from '../geom/shader/radar_frag.glsl'; import warn from '../geom/shader/warn_frag.glsl'; -import pickingMaterial from '../core/engine/picking/pickingMaterial'; +// import pickingMaterial from '../core/engine/picking/pickingMaterial'; /** * point shape 2d circle, traingle text,image @@ -58,7 +58,7 @@ export default class PointLayer extends Layer { // u_zoom: this.scene.getZoom() // }) // mtl.setDefinesvalue('point', true); - mtl.setDefinesvalue('SHAPE', true); + mtl.setDefinesvalue('SHAPE', true); if (shape === 'radar') { mtl.fragmentShader = radar; diff --git a/src/source/csvSource.js b/src/source/csvSource.js index 294407cc53..89dc55b1cc 100644 --- a/src/source/csvSource.js +++ b/src/source/csvSource.js @@ -21,8 +21,7 @@ export default class CSVSource extends Source { if (col.coordinates) { coordinates = col.coordinates; } - if(x && y) - coordinates = [ col[x], col[y] ]; + if (x && y) { coordinates = [ col[x], col[y] ]; } if (x1 && y1) { coordinates = [[ col[x], col[y] ], [ col[x1], col[y1] ]]; } diff --git a/src/source/geojsonSource.js b/src/source/geojsonSource.js index 0a611e8da9..f12872c4c2 100644 --- a/src/source/geojsonSource.js +++ b/src/source/geojsonSource.js @@ -25,19 +25,17 @@ export default class GeojsonSource extends Source { const data = this.get('data'); const selectFeatureIds = []; let featureStyleId = 0; - /* eslint-disable */ - turfMeta.flattenEach(data, (currentFeature, featureIndex, multiFeatureIndex) => { - /* eslint-disable */ - if (featureIndex === (featureId)) { - selectFeatureIds.push(featureStyleId); - } - featureStyleId++; - if (featureIndex > featureId) { - return; - } - }); + turfMeta.flattenEach(data, (currentFeature, featureIndex/* , multiFeatureIndex*/) => { + if (featureIndex === (featureId)) { + selectFeatureIds.push(featureStyleId); + } + featureStyleId++; + if (featureIndex > featureId) { + return; + } + }); return selectFeatureIds; - + } } diff --git a/src/worker/main.worker.js b/src/worker/main.worker.js index 61f73c16d5..eb53453282 100644 --- a/src/worker/main.worker.js +++ b/src/worker/main.worker.js @@ -30,6 +30,5 @@ self.addEventListener('message', e => { } }); self.addEventListener('error', function(e) { - /* eslint-disable */ - console.log('filename:' + e.filename + '\nmessage:' + e.message + '\nline:' + e.lineno); + console.error('filename:' + e.filename + '\nmessage:' + e.message + '\nline:' + e.lineno); }); From 67f439d8a2425ab6aa44e7be4b59859be8a3ad7d Mon Sep 17 00:00:00 2001 From: "wensen.lws" Date: Tue, 20 Nov 2018 20:21:50 +0800 Subject: [PATCH 2/5] chore(dev): do not upload sources and ignore tests --- .npmignore | 3 +++ package.json | 3 +-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.npmignore b/.npmignore index e3b88f8933..fd527239c4 100755 --- a/.npmignore +++ b/.npmignore @@ -70,8 +70,11 @@ test *.un~ .idea bin +bundler demos docs +lib +src temp webpack-dev.config.js webpack.config.js diff --git a/package.json b/package.json index 816c18fbbc..d61e5d7c09 100755 --- a/package.json +++ b/package.json @@ -87,8 +87,7 @@ }, "pre-commit": { "run": [ - "lint", - "test-all" + "lint" ], "silent": false }, From 2665dcf7df71420908e1829ccce6b8608035b14c Mon Sep 17 00:00:00 2001 From: "wensen.lws" Date: Tue, 20 Nov 2018 20:27:39 +0800 Subject: [PATCH 3/5] chore(dev): publish to npmjs.com --- package.json | 3 --- 1 file changed, 3 deletions(-) diff --git a/package.json b/package.json index d61e5d7c09..585c3d8b6c 100755 --- a/package.json +++ b/package.json @@ -91,9 +91,6 @@ ], "silent": false }, - "publishConfig": { - "registry": "http://registry.npm.alibaba-inc.com" - }, "dependencies": { "@antv/g": "^3.1.3", "@antv/util": "~1.2.5", From cf5444f0a6d5018a6a737bee14e7f46e43514440 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=AD=A3=E5=AD=A6?= Date: Thu, 24 Jan 2019 21:06:08 +0800 Subject: [PATCH 4/5] fix(scene): event on map --- package.json | 2 +- src/core/engine/picking/picking.js | 61 ++---------------------------- src/core/scene.js | 11 +----- src/source/geojsonSource.js | 4 +- 4 files changed, 9 insertions(+), 69 deletions(-) diff --git a/package.json b/package.json index cbaf70578a..8ab26df3c2 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@antv/l7", - "version": "1.0.1", + "version": "1.0.3", "description": "Large-scale WebGL-powered Geospatial Data Visualization", "main": "build/l7.js", "browser": "build/l7.js", diff --git a/src/core/engine/picking/picking.js b/src/core/engine/picking/picking.js index e4fb4c2ee1..0dfd718fbe 100755 --- a/src/core/engine/picking/picking.js +++ b/src/core/engine/picking/picking.js @@ -9,10 +9,7 @@ class Picking { this._camera = camera; this._raycaster = new THREE.Raycaster(); this.scene = scene; - this._envents = []; - - // TODO: Match this with the line width used in the picking layers - this._raycaster.linePrecision = 3; + this._raycaster.linePrecision = 10; this._pickingScene = PickingScene; const size = this._renderer.getSize(); this._width = size.width; @@ -21,7 +18,7 @@ class Picking { magFilter: THREE.LinearFilter, format: THREE.RGBAFormat, stencilBuffer: false, - depthBuffer: false + depthBuffer: true }; this._pickingTexture = new THREE.WebGLRenderTarget(this._width, this._height, parameters); @@ -35,38 +32,15 @@ class Picking { _initEvents() { this._resizeHandler = this._resizeTexture.bind(this); window.addEventListener('resize', this._resizeHandler, false); - - // this._mouseUpHandler = this._onMouseUp.bind(this); - // this._world._container.addEventListener('mouseup', this._mouseUpHandler, false); - // this._world._container.addEventListener('mousemove', this._mouseUpHandler, false); - // this._world._container.addEventListener('mousemove', this._onWorldMove.bind(this), false); } pickdata(event) { - const point = { x: event.clientX, y: event.clientY, type: event.type }; + const point = { x: event.pixel.x, y: event.pixel.y, type: event.type }; + const normalisedPoint = { x: 0, y: 0 }; normalisedPoint.x = (point.x / this._width) * 2 - 1; normalisedPoint.y = -(point.y / this._height) * 2 + 1; this._pickAllObject(point, normalisedPoint); } - _onMouseUp(event) { - // Only react to main button click - // if (event.button !== 0) { - // return; - // } - - const point = { x: event.clientX, y: event.clientY, type: event.type }; - const normalisedPoint = { x: 0, y: 0 }; - normalisedPoint.x = (point.x / this._width) * 2 - 1; - normalisedPoint.y = -(point.y / this._height) * 2 + 1; - this._pickAllObject(point, normalisedPoint); - // this._pick(point, normalisedPoint); - } - _onWorldMove() { - - this._needUpdate = true; - } - - // TODO: Ensure this doesn't get out of sync issue with the renderer resize _resizeTexture() { const size = this._renderer.getSize(); @@ -80,28 +54,11 @@ class Picking { _update(point) { const texture = this._pickingTexture; - // if (this._needUpdate) { this._renderer.render(this._pickingScene, this._camera, this._pickingTexture); - // this._needUpdate = false; - // } this.pixelBuffer = new Uint8Array(4); this._renderer.readRenderTargetPixels(texture, point.x, this._height - point.y, 1, 1, this.pixelBuffer); - } - // 添加dom事件 支持 mousedown ,mouseenter mouseleave mousemove mouseover mouseout mouse up - on(type) { - - this._mouseUpHandler = this._onMouseUp.bind(this); - this._world._container.addEventListener(type, this._mouseUpHandler, false); - this._envents.push([ type, this._mouseUpHandler ]); - } - off(type, hander) { - this._world._container.removeEventListener(type, this._mouseUpHandler, false); - this._envents = this._envents.filter(item => { - return item[0] === 'type' && hander === item[1]; - }); - } _filterObject(id) { this._pickingScene.children.forEach((object, index) => { @@ -124,9 +81,7 @@ class Picking { _pick(point, normalisedPoint, layerId) { this._update(point); - // Interpret the pixel as an ID let id = (this.pixelBuffer[2] * 255 * 255) + (this.pixelBuffer[1] * 255) + (this.pixelBuffer[0]); - // Skip if ID is 16646655 (white) as the background returns this if (id === 16646655 || this.pixelBuffer[3] === 0) { id = -999; // return; @@ -134,9 +89,6 @@ class Picking { this._raycaster.setFromCamera(normalisedPoint, this._camera); - // Perform ray intersection on picking scene - // - // TODO: Only perform intersection test on the relevant picking mesh const intersects = this._raycaster.intersectObjects(this._pickingScene.children, true); const _point2d = { x: point.x, y: point.y }; @@ -144,11 +96,6 @@ class Picking { if (intersects.length > 0) { _point3d = intersects[0].point; } - - // Pass along as much data as possible for now until we know more about how - // people use the picking API and what the returned data should be - // - // TODO: Look into the leak potential for passing so much by reference here const item = { layerId, featureId: id - 1, diff --git a/src/core/scene.js b/src/core/scene.js index 30820daa8a..8879215fe2 100644 --- a/src/core/scene.js +++ b/src/core/scene.js @@ -83,14 +83,6 @@ export default class Scene extends Base { getLayers() { return this._layers; } - _addLight() { - // const scene = this._engine._scene; - // //const ambientLight = new THREE.AmbientLight(0xaaaaaa); - // scene.add(ambientLight); - - // const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5); - // scene.add(directionalLight); - } _addLayer() { } @@ -102,11 +94,12 @@ export default class Scene extends Base { 'mousedown', 'mouseleave', 'mouseup', + 'rightclick', 'click', 'dblclick' ]; events.forEach(event => { - this._container.addEventListener(event, e => { + this.map.on(event, e => { // 要素拾取 this._engine._picking.pickdata(e); }, false); diff --git a/src/source/geojsonSource.js b/src/source/geojsonSource.js index cc312a8107..1b1c012568 100644 --- a/src/source/geojsonSource.js +++ b/src/source/geojsonSource.js @@ -37,9 +37,9 @@ export default class GeojsonSource extends Source { return selectFeatureIds; } - getSelectFeature(featureId){ + getSelectFeature(featureId) { const data = this.get('data'); - return data.features[featureId]; + return data.features[featureId]; } } From a6d477480444ea7e0c24456b31fc3b920e05506e Mon Sep 17 00:00:00 2001 From: "yuqi.pyq" Date: Tue, 26 Feb 2019 15:09:49 +0800 Subject: [PATCH 5/5] feat(l7): add shader module --- src/core/scene.js | 2 + src/geom/material/polygonMaterial.js | 9 +++-- src/geom/shader/common.glsl | 2 + src/geom/shader/index.js | 22 +++++------ src/geom/shader/point_frag.glsl | 5 ++- src/geom/shader/project_vert.glsl | 0 src/util/shaderModule.js | 59 ++++++++++++++++++++++++++++ test/unit/shader-module/base-spec.js | 32 +++++++++++++++ 8 files changed, 113 insertions(+), 18 deletions(-) create mode 100644 src/geom/shader/common.glsl create mode 100644 src/geom/shader/project_vert.glsl create mode 100644 src/util/shaderModule.js create mode 100644 test/unit/shader-module/base-spec.js diff --git a/src/core/scene.js b/src/core/scene.js index d9229a2512..121ede7bc8 100644 --- a/src/core/scene.js +++ b/src/core/scene.js @@ -6,6 +6,7 @@ import WorkerPool from './worker'; import { MapProvider } from '../map/provider'; import GaodeMap from '../map/gaodeMap'; import Global from '../global'; +import { compileBuiltinModules } from '../geom/shader'; export default class Scene extends Base { getDefaultCfg() { return Global.scene; @@ -22,6 +23,7 @@ export default class Scene extends Base { this._engine = new Engine(mapContainer, this); this._engine.run(); this.workerPool = new WorkerPool(); + compileBuiltinModules(); } // 为pickup场景添加 object 对象 addPickMesh(object) { diff --git a/src/geom/material/polygonMaterial.js b/src/geom/material/polygonMaterial.js index d47eb72065..da8a598122 100644 --- a/src/geom/material/polygonMaterial.js +++ b/src/geom/material/polygonMaterial.js @@ -1,6 +1,5 @@ -import polygon_frag from '../shader/polygon_frag.glsl'; -import polygon_vert from '../shader/polygon_vert.glsl'; import Material from './material'; +import { getModule } from '../../util/shaderModule'; // export default function PolygonMaterial(options) { // const material = new Material({ // uniforms: { @@ -48,8 +47,10 @@ export default class PolygonMaterial extends Material { this.uniforms = Object.assign(uniforms, this.setUniform(_uniforms)); this.type = 'PolygonMaterial'; this.defines = Object.assign(defines, _defines); - this.vertexShader = polygon_vert; - this.fragmentShader = polygon_frag; + + const { vs, fs } = getModule('polygon'); + this.vertexShader = vs; + this.fragmentShader = fs; this.transparent = true; } } diff --git a/src/geom/shader/common.glsl b/src/geom/shader/common.glsl new file mode 100644 index 0000000000..09462af13e --- /dev/null +++ b/src/geom/shader/common.glsl @@ -0,0 +1,2 @@ +#define PI 3.14159265359 +#define TWO_PI 6.28318530718 \ No newline at end of file diff --git a/src/geom/shader/index.js b/src/geom/shader/index.js index 525a698d2d..fffbfda42a 100644 --- a/src/geom/shader/index.js +++ b/src/geom/shader/index.js @@ -1,14 +1,12 @@ import point_frag from '../shader/point_frag.glsl'; import point_vert from '../shader/point_vert.glsl'; -const shaderslib = { - pointShader: { - fragment: point_frag, - vertex: point_vert - } -}; -// for (const programName in shaderslib) { -// const program = shaderslib[programName]; -// program.fragment = ShaderFactory.parseIncludes(program.fragment); -// program.vertex = ShaderFactory.parseIncludes(program.vertex); -// } -export default shaderslib; +import polygon_frag from '../shader/polygon_frag.glsl'; +import polygon_vert from '../shader/polygon_vert.glsl'; +import common from './common.glsl'; +import { registerModule } from '../../util/shaderModule'; + +export function compileBuiltinModules() { + registerModule('point', { vs: point_vert, fs: point_frag }); + registerModule('common', { vs: common, fs: common }); + registerModule('polygon', { vs: polygon_vert, fs: polygon_frag }); +} diff --git a/src/geom/shader/point_frag.glsl b/src/geom/shader/point_frag.glsl index 238c972638..eecea0605c 100644 --- a/src/geom/shader/point_frag.glsl +++ b/src/geom/shader/point_frag.glsl @@ -1,7 +1,8 @@ precision highp float; -#define PI 3.14159265359 -#define TWO_PI 6.28318530718 + +#pragma import "common" + uniform float u_strokeWidth; uniform vec4 u_stroke; uniform float u_opacity; diff --git a/src/geom/shader/project_vert.glsl b/src/geom/shader/project_vert.glsl new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/util/shaderModule.js b/src/util/shaderModule.js new file mode 100644 index 0000000000..b0a354194f --- /dev/null +++ b/src/util/shaderModule.js @@ -0,0 +1,59 @@ +const SHADER_TYPE = { + VS: 'vs', + FS: 'fs' +}; +const moduleCache = {}; +const rawContentCache = {}; +const precisionRegExp = /precision\s+(high|low|medium)p\s+float/; +const globalDefaultprecision = '#ifdef GL_FRAGMENT_PRECISION_HIGH\n precision highp float;\n #else\n precision mediump float;\n#endif\n'; +const includeRegExp = /#pragma include (["^+"]?["\ "[a-zA-Z_0-9](.*)"]*?)/g; + +function processModule(rawContent, includeList, type) { + return rawContent.replace(includeRegExp, (_, strMatch) => { + const includeOpt = strMatch.split(' '); + const includeName = includeOpt[0].replace(/"/g, ''); + + if (includeList.indexOf(includeName) > -1) { + return ''; + } + + let txt = rawContentCache[includeName][type]; + includeList.push(includeName); + + txt = processModule(txt, includeList, type); + return txt; + }); +} + +export function registerModule(moduleName, { vs, fs }) { + rawContentCache[moduleName] = { + [SHADER_TYPE.VS]: vs, + [SHADER_TYPE.FS]: fs + }; +} + +export function getModule(moduleName) { + if (moduleCache[moduleName]) { + return moduleCache[moduleName]; + } + + let vs = rawContentCache[moduleName][SHADER_TYPE.VS]; + let fs = rawContentCache[moduleName][SHADER_TYPE.FS]; + + vs = processModule(vs, [], SHADER_TYPE.VS); + fs = processModule(fs, [], SHADER_TYPE.FS); + + /** + * set default precision for fragment shader + * https://stackoverflow.com/questions/28540290/why-it-is-necessary-to-set-precision-for-the-fragment-shader + */ + if (!precisionRegExp.test(fs)) { + fs = globalDefaultprecision + fs; + } + + moduleCache[moduleName] = { + [SHADER_TYPE.VS]: vs.trim(), + [SHADER_TYPE.FS]: fs.trim() + }; + return moduleCache[moduleName]; +} diff --git a/test/unit/shader-module/base-spec.js b/test/unit/shader-module/base-spec.js new file mode 100644 index 0000000000..8f2b35c079 --- /dev/null +++ b/test/unit/shader-module/base-spec.js @@ -0,0 +1,32 @@ +import { expect } from 'chai'; +import { registerModule, getModule } from '../../../src/util/shaderModule'; + +describe('test shader module', function() { + + const vs = ` + #define PI 3.14 + `; + + const commonModule = { + vs, + fs: vs + }; + + const module1 = { + vs: ` + #pragma include "common" + `, + fs: '' + }; + + registerModule('common', commonModule); + registerModule('module1', module1); + + it('should import a module correctly.', function() { + const { vs, fs } = getModule('module1'); + + expect(vs).eq('#define PI 3.14'); + expect(fs).eq(''); + }); + +});