refactor: 更新threejs 依赖

This commit is contained in:
thinkinggis 2020-04-18 21:22:44 +08:00
parent f0061a5ec0
commit 2f19f2c419
12 changed files with 1266 additions and 413 deletions

View File

@ -102,6 +102,7 @@
"rollup-pluginutils": "^2.8.2",
"sass-loader": "^7.1.0",
"style-loader": "^1.0.0",
"three": "0.115.0",
"styled-components": "^3.4.6",
"stylelint": "^9.5.0",
"stylelint-config-recommended": "^2.1.0",

View File

@ -40,7 +40,6 @@
"lodash": "^4.17.15",
"merge-json-schemas": "1.0.0",
"polyline-miter-util": "^1.0.1",
"three": "^0.111.0",
"reflect-metadata": "^0.1.13"
},
"devDependencies": {

View File

@ -8,7 +8,6 @@ import LineLayer from './line/index';
import PointLayer from './point';
import PolygonLayer from './polygon';
import RasterLayer from './raster';
import ThreeJSLayer from './three';
// import ConfigSchemaValidationPlugin from './plugins/ConfigSchemaValidationPlugin';
import DataMappingPlugin from './plugins/DataMappingPlugin';
@ -138,5 +137,4 @@ export {
ImageLayer,
RasterLayer,
HeatmapLayer,
ThreeJSLayer,
};

View File

@ -1,176 +0,0 @@
/**
* inspired by threebox & Mapbox examples
* @see https://github.com/peterqliu/threebox/blob/master/src/Threebox.js
* @see https://github.com/peterqliu/threebox/blob/master/examples/Object3D.html
*/
import { IMercator } from '@antv/l7-core';
import {
AnimationMixer,
Camera,
Matrix4,
PCFSoftShadowMap,
PerspectiveCamera,
Scene,
WebGLRenderer,
} from 'three';
import BaseLayer from '../core/BaseLayer';
const DEG2RAD = Math.PI / 180;
export default class ThreeJSLayer extends BaseLayer<{
onAddMeshes: (threeScene: Scene, layer: ThreeJSLayer) => void;
}> {
public name: string = 'ThreeJSLayer';
public type: string = 'custom';
private scene: Scene;
private camera: Camera;
private renderer: WebGLRenderer;
private animateMixer: AnimationMixer[] = [];
// 地图中点墨卡托坐标
private center: IMercator;
// 初始状态相机变换矩阵
private cameraTransform: Matrix4;
/**
*
*/
public getModelMatrix(
lnglat: [number, number],
altitude: number = 0,
rotation: [number, number, number] = [0, 0, 0],
scale: [number, number, number] = [1, 1, 1],
): Matrix4 {
return new Matrix4().fromArray(
this.mapService.getModelMatrix(
lnglat,
altitude,
rotation,
scale,
this.center,
),
);
}
public buildModels() {
const canvas = this.rendererService.getCanvas();
const gl = this.rendererService.getGLContext();
if (canvas && gl) {
const center = this.mapService.getCenter();
this.center = this.mapService.lngLatToMercator(
[center.lng, center.lat],
0,
);
const { x, y, z } = this.center;
this.cameraTransform = new Matrix4().makeTranslation(x, y, z);
this.renderer = new WebGLRenderer({
canvas,
context: gl,
antialias: true,
});
// L7 负责 clear
this.renderer.autoClear = false;
// 是否需要 gamma correction?
this.renderer.gammaFactor = 2.2;
this.renderer.shadowMap.enabled = true;
// this.renderer.shadowMap.type = PCFSoftShadowMap;
this.scene = new Scene();
this.camera = new PerspectiveCamera(45, 1, 1, 2000000);
const config = this.getLayerConfig();
if (config && config.onAddMeshes) {
config.onAddMeshes(this.scene, this);
}
}
}
public renderModels() {
return this.mapService.constructor.name === 'AMapService'
? this.renderAMapModels()
: this.renderMapboxModels();
}
public renderMapboxModels() {
// const { width, height } = this.rendererService.getViewportSize();
// this.renderer.setSize(width, height, false);
const gl = this.rendererService.getGLContext();
gl.frontFace(gl.CCW);
gl.enable(gl.CULL_FACE);
gl.cullFace(gl.FRONT);
// 同步相机
const mercatorMatrix = new Matrix4().fromArray(
// @ts-ignore
this.mapService.map.transform.customLayerMatrix(),
);
this.camera.projectionMatrix = mercatorMatrix.multiply(
this.cameraTransform,
);
this.renderer.state.reset();
this.renderer.render(this.scene, this.camera);
this.rendererService.setBaseState();
this.animateMixer.forEach((mixer: AnimationMixer) => {
mixer.update(this.getTime());
});
return this;
}
public renderAMapModels() {
const gl = this.rendererService.getGLContext();
gl.frontFace(gl.CCW);
gl.enable(gl.CULL_FACE);
gl.cullFace(gl.BACK);
// @ts-ignore
const mapCamera = this.mapService.map.getCameraState();
const camera = this.camera;
let { pitch, rotation } = mapCamera;
const { fov, near, far, height, aspect } = mapCamera;
pitch *= DEG2RAD;
rotation *= DEG2RAD;
// @ts-ignore
camera.fov = (180 * fov) / Math.PI;
// @ts-ignore
camera.aspect = aspect;
// @ts-ignore
camera.near = near;
// @ts-ignore
camera.far = far;
// @ts-ignore
camera.updateProjectionMatrix();
camera.position.z = height * Math.cos(pitch);
camera.position.x = height * Math.sin(pitch) * Math.sin(rotation);
camera.position.y = -height * Math.sin(pitch) * Math.cos(rotation);
camera.up.x = -Math.cos(pitch) * Math.sin(rotation);
camera.up.y = Math.cos(pitch) * Math.cos(rotation);
camera.up.z = Math.sin(pitch);
camera.lookAt(0, 0, 0);
camera.position.x += mapCamera.position.x;
camera.position.y += -mapCamera.position.y;
this.renderer.state.reset();
this.renderer.autoClear = false;
this.renderer.render(this.scene, this.camera);
this.animateMixer.forEach((mixer: AnimationMixer) => {
mixer.update(this.getTime());
});
return this;
}
public addAnimateMixer(mixer: AnimationMixer) {
this.animateMixer.push(mixer);
}
protected getConfigSchema() {
return {
properties: {
// opacity: {
// type: 'altitude',
// minimum: 0,
// maximum: 100,
// },
},
};
}
}

View File

@ -39,10 +39,13 @@
},
"homepage": "https://github.com/antvis/L7#readme",
"dependencies": {
"three": "^0.115.0",
"@antv/l7": "2.1.15",
"@babel/runtime": "^7.7.7",
"rollup": "^2.3.3",
"rollup-plugin-less": "^1.1.2"
},
"devDependencies": {
"three": "^0.115.0"
}
}

View File

@ -55,7 +55,7 @@ export default class GlTFThreeJSDemo extends React.Component {
// 根据 GeoJSON 数据放置模型
layer.getSource().data.dataArray.forEach(({ coordinates }) => {
const gltfScene = gltf.scene;
gltfScene.applyMatrix(
gltfScene.applyMatrix4(
// 生成模型矩阵
layer.getModelMatrix(
[coordinates[0], coordinates[1]], // 经纬度坐标

View File

@ -1,4 +1,4 @@
import { Scene, PolygonLayer, ThreeJSLayer } from '@antv/l7';
import { PolygonLayer, Scene } from '@antv/l7';
import { GaodeMap, Mapbox } from '@antv/l7-maps';
import { ThreeLayer, ThreeRender } from '@antv/l7-three';
import * as React from 'react';
@ -75,7 +75,7 @@ export default class GlTFThreeJSDemo extends React.Component {
// 根据 GeoJSON 数据放置模型
layer.getSource().data.dataArray.forEach(({ coordinates }) => {
const gltfScene = gltf.scene.clone();
gltfScene.applyMatrix(
gltfScene.applyMatrix4(
// 生成模型矩阵
layer.getModelMatrix(
[coordinates[0], coordinates[1]], // 经纬度坐标

View File

@ -87,7 +87,7 @@ export default class GlTFThreeJSDemo extends React.Component {
// 根据 GeoJSON 数据放置模型
layer.getSource().data.dataArray.forEach(({ coordinates }) => {
const gltfScene = gltf.scene;
gltfScene.applyMatrix(
gltfScene.applyMatrix4(
// 生成模型矩阵
layer.getModelMatrix(
[coordinates[0], coordinates[1]], // 经纬度坐标

View File

@ -5,10 +5,8 @@ import Arc2DLineDemo from './components/Arc2DLine';
import ArcLineDemo from './components/Arcline';
import CityBuildingLayerDemo from './components/citybuilding';
import Column from './components/column';
import CustomThreeJSDemo from './components/CustomThreeJSLayer';
import DashLineDemo from './components/dash';
import DataUpdate from './components/data_update';
import GlTFThreeJSDemo from './components/GlTFThreeJSDemo';
import HeatMapDemo from './components/HeatMap';
import HeatMapDemo3D from './components/heatmap3d';
import HeatMap3D_2 from './components/heatmap2';
@ -49,7 +47,5 @@ storiesOf('图层', module)
.add('网格热力图', () => <HexagonLayerDemo />)
.add('栅格', () => <RasterLayerDemo />)
.add('图片', () => <ImageLayerDemo />)
.add('Three.js 图层', () => <CustomThreeJSDemo />)
.add('glTF 图层', () => <GlTFThreeJSDemo />)
.add('网格测试', () => <GridTest />)
.add('世界地图', () => <WorldDemo />);

View File

@ -1,102 +0,0 @@
import { PointLayer, Scene, ThreeJSLayer } from '@antv/l7';
import { GaodeMap, Mapbox } from '@antv/l7-maps';
import * as React from 'react';
import {
BackSide,
BoxGeometry,
DirectionalLight,
Mesh,
MeshLambertMaterial,
Matrix4,
Scene as ThreeScene,
} from 'three';
// @ts-ignore
import data from '../data/data.json';
export default class ThreeJSLayerComponent extends React.Component {
// @ts-ignore
private scene: Scene;
public componentWillUnmount() {
this.scene.destroy();
}
public async componentDidMount() {
const response = await fetch(
'https://gw.alipayobjects.com/os/basement_prod/d3564b06-670f-46ea-8edb-842f7010a7c6.json',
);
const pointsData = await response.json();
const scene = new Scene({
id: 'map',
map: new Mapbox({
center: [120.19382669582967, 30.258134],
pitch: 60,
rotation: 30,
zoom: 16,
}),
});
this.scene = scene;
// const pointLayer = new PointLayer({})
// .source(pointsData, {
// cluster: true,
// })
// .shape('circle')
// .scale('point_count', {
// type: 'quantile',
// })
// .size('point_count', [5, 10, 15, 20, 25])
// .color('red')
// .style({
// opacity: 0.3,
// strokeWidth: 1,
// });
// scene.addLayer(pointLayer);
const threeJSLayer = new ThreeJSLayer({
enableMultiPassRenderer: false,
onAddMeshes: (threeScene: ThreeScene, layer: ThreeJSLayer) => {
// 添加光源
const directionalLight1 = new DirectionalLight(0xffffff);
directionalLight1.position.set(0, -70, 100).normalize();
threeScene.add(directionalLight1);
const directionalLight2 = new DirectionalLight(0xffffff);
directionalLight2.position.set(0, 70, 100).normalize();
threeScene.add(directionalLight2);
const geometry = new BoxGeometry(20, 20, 20);
const redMaterial = new MeshLambertMaterial({
color: 0xffffff,
side: BackSide,
});
const cube = new Mesh(geometry, redMaterial);
cube.applyMatrix(
layer.getModelMatrix([120.19382669582967, 30.258134], 10, [
0,
0,
0,
]) as Matrix4,
);
cube.frustumCulled = false;
threeScene.add(cube);
},
}).source(pointsData);
scene.addLayer(threeJSLayer);
}
public render() {
return (
<div
id="map"
style={{
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
}}
/>
);
}
}

View File

@ -1,96 +0,0 @@
import { Scene, ThreeJSLayer } from '@antv/l7';
import { Mapbox } from '@antv/l7-maps';
import * as React from 'react';
import { DirectionalLight, Matrix4, Scene as ThreeScene } from 'three';
// tslint:disable-next-line:no-submodule-imports
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
export default class GlTFThreeJSDemo extends React.Component {
// @ts-ignore
private scene: Scene;
public componentWillUnmount() {
this.scene.destroy();
}
public async componentDidMount() {
const response = await fetch(
'https://gw.alipayobjects.com/os/basement_prod/893d1d5f-11d9-45f3-8322-ee9140d288ae.json',
);
const pointsData = await response.json();
const scene = new Scene({
id: 'map',
map: new Mapbox({
center: [121.434765, 31.256735],
pitch: 45,
rotation: 30,
zoom: 18,
}),
});
this.scene = scene;
const threeJSLayer = new ThreeJSLayer({
enableMultiPassRenderer: false,
onAddMeshes: (threeScene: ThreeScene, layer: ThreeJSLayer) => {
// 添加光源
const directionalLight1 = new DirectionalLight(0xffffff);
directionalLight1.position.set(0, -70, 100).normalize();
threeScene.add(directionalLight1);
const directionalLight2 = new DirectionalLight(0xffffff);
directionalLight2.position.set(0, 70, 100).normalize();
threeScene.add(directionalLight2);
// 使用 Three.js glTFLoader 加载模型
const loader = new GLTFLoader();
loader.load(
// 'https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Models/master/2.0/DamagedHelmet/glTF/DamagedHelmet.gltf',
// 'https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Models/master/2.0/AnimatedCube/glTF/AnimatedCube.gltf',
'https://gw.alipayobjects.com/os/antvdemo/assets/gltf/radar/34M_17.gltf',
// 'https://gw.alipayobjects.com/os/bmw-prod/3ca0a546-92d8-4ba0-a89c-017c218d5bea.gltf',
(gltf) => {
// 根据 GeoJSON 数据放置模型
layer.getSource().data.dataArray.forEach(({ coordinates }) => {
const gltfScene = gltf.scene.clone();
gltfScene.applyMatrix(
// 生成模型矩阵
layer.getModelMatrix(
[coordinates[0], coordinates[1]], // 经纬度坐标
0, // 高度,单位米
[Math.PI / 2, 0, 0], // 沿 XYZ 轴旋转角度
[5, 5, 5], // 沿 XYZ 轴缩放比例
),
);
// 向场景中添加模型
threeScene.add(gltfScene);
});
// 重绘图层
layer.render();
},
);
},
}).source(pointsData, {
parser: {
type: 'json',
x: 'longitude',
y: 'latitude',
},
});
scene.addLayer(threeJSLayer);
}
public render() {
return (
<div
id="map"
style={{
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
}}
/>
);
}
}

1284
yarn.lock

File diff suppressed because it is too large Load Diff