From 1a161121ffa7c4d4a1c3e7f3deab5ddc3377b728 Mon Sep 17 00:00:00 2001 From: 2912401452 <2912401452@qq.com> Date: Fri, 17 Sep 2021 17:19:48 +0800 Subject: [PATCH 1/5] =?UTF-8?q?feat:=20gaodemap2=20=E5=AF=B9=E9=BD=90?= =?UTF-8?q?=E7=9B=B8=E6=9C=BA=EF=BC=88=E8=A7=86=E5=9B=BE=E3=80=81=E6=8A=95?= =?UTF-8?q?=E5=BD=B1=E7=9F=A9=E9=98=B5=EF=BC=89=20-=20=E5=B0=9A=E6=9C=AA?= =?UTF-8?q?=E5=AF=B9=E9=BD=90=E6=A8=A1=E5=9E=8B=E7=9F=A9=E9=98=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/three/src/core/baseLayer.ts | 8 + packages/three/src/core/threeRenderService.ts | 62 +++++++- stories/3D_Model/Components/amap2_three.tsx | 143 ++++++++++++++++++ stories/3D_Model/Components/threeRender.tsx | 1 - stories/3D_Model/model.stories.tsx | 2 + 5 files changed, 211 insertions(+), 5 deletions(-) create mode 100644 stories/3D_Model/Components/amap2_three.tsx diff --git a/packages/three/src/core/baseLayer.ts b/packages/three/src/core/baseLayer.ts index 53bdbedd30..6bbc36b7d7 100644 --- a/packages/three/src/core/baseLayer.ts +++ b/packages/three/src/core/baseLayer.ts @@ -29,6 +29,7 @@ export default class ThreeJSLayer implements IThreeJSLayer { public type: string = 'custom'; protected threeRenderService: IThreeRenderService; + // 构建 threejs 的 scene private scene: Scene = new Scene(); private renderer: WebGLRenderer; private animateMixer: AnimationMixer[] = []; @@ -67,16 +68,23 @@ export default class ThreeJSLayer } } public renderModels() { + // 获取到 L7 的 gl const gl = this.rendererService.getGLContext(); this.rendererService.setCustomLayerDefaults(); const cullFace = this.mapService.constructor.name === 'AMapService' ? gl.BACK : gl.FRONT; gl.cullFace(cullFace); + + // threejs 的 renderer const renderer = this.threeRenderService.renderer; renderer.state.reset(); renderer.autoClear = false; + + // 获取相机 (不同的地图获取对应的方式不同) const camera = this.threeRenderService.getRenderCamera(); + renderer.render(this.scene, camera); + this.rendererService.setBaseState(); this.animateMixer.forEach((mixer: AnimationMixer) => { mixer.update(this.getTime()); diff --git a/packages/three/src/core/threeRenderService.ts b/packages/three/src/core/threeRenderService.ts index 283dece4a1..19f3da57b1 100644 --- a/packages/three/src/core/threeRenderService.ts +++ b/packages/three/src/core/threeRenderService.ts @@ -25,6 +25,7 @@ export class ThreeRenderService implements IThreeRenderService { public renderer: WebGLRenderer; public camera: Camera; public center: IMercator; + public aspect: number; private scene: ThreeScene; // 初始状态相机变换矩阵 @@ -37,6 +38,7 @@ export class ThreeRenderService implements IThreeRenderService { private readonly mapService: IMapService; public init() { + // 从 L7 的 renderer 中获取可视化层的 canvas/gl const canvas = this.rendererService.getCanvas() as HTMLCanvasElement; const gl = this.rendererService.getGLContext(); if (canvas && gl) { @@ -48,6 +50,8 @@ export class ThreeRenderService implements IThreeRenderService { } const { x, y, z } = this.center; this.cameraTransform = new Matrix4().makeTranslation(x, y, z); + + // 根据 L7 的 canvas/gl 构建 threejs 的 renderer this.renderer = new WebGLRenderer({ canvas, context: gl, @@ -61,12 +65,30 @@ export class ThreeRenderService implements IThreeRenderService { // this.renderer.shadowMap.type = PCFSoftShadowMap; this.scene = new ThreeScene(); - this.camera = new PerspectiveCamera(45, 1, 1, 2000000); + + this.aspect = gl.drawingBufferWidth / gl.drawingBufferHeight; + this.camera = new PerspectiveCamera(45, this.aspect, 1, 20000000); } public getRenderCamera(): Camera { - return this.mapService.constructor.name === 'AMapService' - ? this.AMapCamera() - : this.mapboxCamera(); + /** + * map version + * GAODE1.x + * GAODE2.x + * MAPBOX + */ + switch (this.mapService.version) { + case 'GAODE1.x': + return this.AMapCamera(); + case 'GAODE2.x': + return this.AMap2Camera(); + case 'MAPBOX': + return this.mapboxCamera(); + default: + return this.AMapCamera(); + } + // return this.mapService.constructor.name === 'AMapService' + // ? this.AMapCamera() + // : this.mapboxCamera(); } private mapboxCamera(): Camera { @@ -109,4 +131,36 @@ export class ThreeRenderService implements IThreeRenderService { camera.position.y += -mapCamera.position.y; return camera; } + + private AMap2Camera(): Camera { + // @ts-ignore + const customCoords = this.mapService.map.customCoords; + customCoords.getCenter(); + + const camera = this.camera; + const { + near, + far, + fov, + up, + lookAt, + position, + } = customCoords.getCameraParams(); + // @ts-ignore + camera.near = near; + // @ts-ignore + camera.far = far; + // @ts-ignore + camera.fov = fov; + // @ts-ignore + camera.position.set(...position); + // @ts-ignore + camera.up.set(...up); + // @ts-ignore + camera.lookAt(...lookAt); + // @ts-ignore + camera.updateProjectionMatrix(); + + return camera; + } } diff --git a/stories/3D_Model/Components/amap2_three.tsx b/stories/3D_Model/Components/amap2_three.tsx new file mode 100644 index 0000000000..bb55abd1a2 --- /dev/null +++ b/stories/3D_Model/Components/amap2_three.tsx @@ -0,0 +1,143 @@ +import { Scene } from '@antv/l7'; +import { GaodeMap, GaodeMapV2, Mapbox } from '@antv/l7-maps'; +import { ThreeLayer, ThreeRender } from '@antv/l7-three'; +import * as React from 'react'; +// import { DirectionalLight, Scene as ThreeScene } from 'three'; +import * as THREE 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 GaodeMapV2({ + center: [111.4453125, 32.84267363195431], + pitch: 45, + rotation: 30, + zoom: 15, + }), + }); + this.scene = scene; + scene.registerRenderService(ThreeRender); + scene.on('loaded', () => { + const threeJSLayer = new ThreeLayer({ + enableMultiPassRenderer: false, + onAddMeshes: (threeScene: THREE.Scene, layer: ThreeLayer) => { + threeScene.add(new THREE.AmbientLight(0xffffff)); + const sunlight = new THREE.DirectionalLight(0xffffff, 0.25); + sunlight.position.set(0, 80000000, 100000000); + sunlight.matrixWorldNeedsUpdate = true; + threeScene.add(sunlight); + // 使用 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/antvdemo/assets/gltf/duck/Duck.gltf', // duck + // 'https://gw.alipayobjects.com/os/antvdemo/assets/gltf/truck/CesiumMilkTruck.gltf', // Truck + // 'https://gw.alipayobjects.com/os/antvdemo/assets/gltf/man/CesiumMan.gltf', + 'https://gw.alipayobjects.com/os/bmw-prod/3ca0a546-92d8-4ba0-a89c-017c218d5bea.gltf', + (gltf) => { + // console.log(gltf) + const gltfScene = gltf.scene; + // gltfScene.rotation.set(90, 90, 0) + layer.getSource().data.dataArray.forEach(({ coordinates }) => { + const gltfScene = gltf.scene; + + gltfScene.scale.set(10, 10, 10); + // gltfScene.applyMatrix4( + // // 生成模型矩阵 + // layer.getModelMatrix( + // [coordinates[0], coordinates[1]], // 经纬度坐标 + // 0, // 高度,单位米/ + // [Math.PI / 2, -Math.PI, 0], // 沿 XYZ 轴旋转角度 + // [100, 100, 100], // 沿 XYZ 轴缩放比例 + // ), + // ); + + // gltfScene.applyMatrix4( + // // 生成模型矩阵 + // layer.getModelMatrix( + // // [coordinates[0], coordinates[1]], // 经纬度坐标 + // [0, 0], // 经纬度坐标 + // 0, // 高度,单位米/ + // [Math.PI / 2, -Math.PI, 0], // 沿 XYZ 轴旋转角度 + // [10000, 10000, 10000], // 沿 XYZ 轴缩放比例 + // ), + // ); + + const animations = gltf.animations; + if (animations && animations.length) { + const mixer = new THREE.AnimationMixer(gltfScene); + // @ts-ignore + // for (let i = 0; i < 1; i++) { + const animation = animations[2]; + + // There's .3333 seconds junk at the tail of the Monster animation that + // keeps it from looping cleanly. Clip it at 3 seconds + + const action = mixer.clipAction(animation); + + action.play(); + // } + layer.addAnimateMixer(mixer); + } + + // 向场景中添加模型 + // threeScene.add(gltfScene); + }); + + threeScene.add(gltfScene); + // 重绘图层 + layer.render(); + }, + ); + }, + }) + .source({ + type: 'FeatureCollection', + features: [ + { + type: 'Feature', + properties: {}, + geometry: { + type: 'Point', + coordinates: [111.4453125, 32.84267363195431], + }, + }, + ], + }) + .animate(true); + scene.addLayer(threeJSLayer); + }); + } + + public render() { + return ( +
+ ); + } +} diff --git a/stories/3D_Model/Components/threeRender.tsx b/stories/3D_Model/Components/threeRender.tsx index 43f7cce41f..10eb823bee 100644 --- a/stories/3D_Model/Components/threeRender.tsx +++ b/stories/3D_Model/Components/threeRender.tsx @@ -64,7 +64,6 @@ export default class GlTFThreeJSDemo extends React.Component { .active(true) .size(20); scene.addLayer(imageLayer); - const threeJSLayer = new ThreeLayer({ enableMultiPassRenderer: false, onAddMeshes: (threeScene: THREE.Scene, layer: ThreeLayer) => { diff --git a/stories/3D_Model/model.stories.tsx b/stories/3D_Model/model.stories.tsx index b031ad6727..3a335f8e01 100644 --- a/stories/3D_Model/model.stories.tsx +++ b/stories/3D_Model/model.stories.tsx @@ -1,10 +1,12 @@ import { storiesOf } from '@storybook/react'; import * as React from 'react'; import AMapModel from './Components/amap_three'; +import AMap2Model from './Components/amap2_three'; import MapboxModel from './Components/mapbox_three'; import ThreeRender from './Components/threeRender'; storiesOf('3D 模型', module) .add('ThreeJS Render', () => , {}) .add('高德模型1.x', () => , {}) + .add('高德模型2.x', () => , {}) .add('Mapbox模型', () => , {}); From 3da2676b0e6807d1ebccdab3b8c672d3ef4f2b5a Mon Sep 17 00:00:00 2001 From: 2912401452 <2912401452@qq.com> Date: Sat, 18 Sep 2021 16:02:27 +0800 Subject: [PATCH 2/5] =?UTF-8?q?feat:=20=E8=A1=A5=E5=85=A8=E9=AB=98?= =?UTF-8?q?=E5=BE=B7=E5=9C=B0=E5=9B=BE=202.0=20=E7=9A=84=E6=A8=A1=E5=9E=8B?= =?UTF-8?q?=E5=8A=A0=E8=BD=BD=E8=83=BD=E5=8A=9B=EF=BC=8C=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E6=A8=A1=E5=9E=8B=E7=9A=84=E7=BB=8F=E7=BA=AC=E5=BA=A6=E7=A7=BB?= =?UTF-8?q?=E5=8A=A8=E8=83=BD=E5=8A=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/maps/src/amap/map.ts | 6 ++ packages/maps/src/amap2/map.ts | 6 +- packages/maps/src/mapbox/map.ts | 12 +++ packages/three/src/core/IThreeJSLayer.ts | 33 +++++++++ packages/three/src/core/baseLayer.ts | 60 ++++++++++++--- packages/three/src/index.ts | 7 +- stories/3D_Model/Components/amap2_three.tsx | 77 ++++++++++++-------- stories/3D_Model/Components/amap_three.tsx | 28 ++++++- stories/3D_Model/Components/mapbox_three.tsx | 19 ++++- 9 files changed, 198 insertions(+), 50 deletions(-) create mode 100644 packages/three/src/core/IThreeJSLayer.ts diff --git a/packages/maps/src/amap/map.ts b/packages/maps/src/amap/map.ts index 4cc64e9a16..68b59e357f 100644 --- a/packages/maps/src/amap/map.ts +++ b/packages/maps/src/amap/map.ts @@ -275,6 +275,12 @@ export default class AMapService }; } + public lngLatToCoord(lnglat: [number, number]): any { + // @ts-ignore + let { x, y } = this.map.lngLatToGeodeticCoord(lnglat) + return [x, -y] + } + public lngLatToMercator( lnglat: [number, number], altitude: number, diff --git a/packages/maps/src/amap2/map.ts b/packages/maps/src/amap2/map.ts index 547b1914ec..f9155490e3 100644 --- a/packages/maps/src/amap2/map.ts +++ b/packages/maps/src/amap2/map.ts @@ -370,7 +370,10 @@ export default class AMapService scale: [number, number, number] = [1, 1, 1], origin: IMercator = { x: 0, y: 0, z: 0 }, ): number[] { - const flat = this.viewport.projectFlat(lnglat); + + // const flat = this.viewport.projectFlat(lnglat); + // @ts-ignore + const flat = this.map.customCoords.lngLatToCoord(lnglat) // @ts-ignore const modelMatrix = mat4.create(); @@ -379,6 +382,7 @@ export default class AMapService modelMatrix, vec3.fromValues(flat[0], flat[1], altitude), ); + mat4.scale( modelMatrix, modelMatrix, diff --git a/packages/maps/src/mapbox/map.ts b/packages/maps/src/mapbox/map.ts index 3073ac8c35..7acae87b6f 100644 --- a/packages/maps/src/mapbox/map.ts +++ b/packages/maps/src/mapbox/map.ts @@ -236,6 +236,18 @@ export default class MapboxService public lngLatToContainer(lnglat: [number, number]): IPoint { return this.map.project(lnglat); } + + /** + * 将经纬度转成墨卡托坐标 + * @param lnglat + * @returns + */ + public lngLatToCoord(lnglat: [number, number]) { + // @ts-ignore + let { x, y } = this.lngLatToMercator(lnglat, 0); + return [x, y] as [number, number]; + } + public lngLatToMercator( lnglat: [number, number], altitude: number, diff --git a/packages/three/src/core/IThreeJSLayer.ts b/packages/three/src/core/IThreeJSLayer.ts new file mode 100644 index 0000000000..a0bbca5b48 --- /dev/null +++ b/packages/three/src/core/IThreeJSLayer.ts @@ -0,0 +1,33 @@ +import { ILayer } from '@antv/l7'; +import { + AnimationMixer, + Matrix4, + Object3D + } from 'three'; + +export type ILngLat = [number, number] + +export interface IThreeJSLayer extends ILayer { + // 获取对应地图的经纬度模型矩阵 + getModelMatrix( + lnglat: ILngLat, + altitude: number, + rotation: [number, number, number], + scale: [number, number, number], + ): Matrix4; + + // 获取对应地图的经纬度平移矩阵 + getTranslateMatrix(lnglat: ILngLat, altitude?: number): Matrix4; + + // 设置模型对应地图在经纬度和高度方向的平移 + setObjectLngLat(object: Object3D, lnglat: ILngLat, altitude?: number): void; + + // 根据经纬度设置模型对应地图的平移 + setObjectLngLat(object: Object3D, lnglat: ILngLat, altitude?: number): void; + + // 返回物体在场景中的经纬度 + getObjectLngLat(object: Object3D): ILngLat; + + // 增加加载模型的动画混合器 + addAnimateMixer(mixer: AnimationMixer): void; +} \ No newline at end of file diff --git a/packages/three/src/core/baseLayer.ts b/packages/three/src/core/baseLayer.ts index 6bbc36b7d7..757df65af3 100644 --- a/packages/three/src/core/baseLayer.ts +++ b/packages/three/src/core/baseLayer.ts @@ -7,21 +7,14 @@ import { PerspectiveCamera, Scene, WebGLRenderer, + Object3D } from 'three'; import { IThreeRenderService, ThreeRenderServiceType, } from './threeRenderService'; +import { IThreeJSLayer, ILngLat } from './IThreeJSLayer' const DEG2RAD = Math.PI / 180; -interface IThreeJSLayer extends ILayer { - getModelMatrix( - lnglat: [number, number], - altitude: number, - rotation: [number, number, number], - scale: [number, number, number], - ): Matrix4; - addAnimateMixer(mixer: AnimationMixer): void; -} export default class ThreeJSLayer extends BaseLayer<{ onAddMeshes: (threeScene: Scene, layer: ThreeJSLayer) => void; @@ -36,10 +29,9 @@ export default class ThreeJSLayer // 地图中点墨卡托坐标 private center: IMercator; - // 初始状态相机变换矩阵 /** - * 根据模型 + * 根据数据计算对应地图的模型矩阵 不同地图主要是点位偏移不同 */ public getModelMatrix( lnglat: [number, number], @@ -58,7 +50,53 @@ export default class ThreeJSLayer ); } + /** + * 获取平移矩阵 + * @param lnglat + * @param altitude + * @returns + */ + public getTranslateMatrix( lnglat: ILngLat, altitude: number = 0,) { + return this.getModelMatrix( lnglat, altitude, [0, 0, 0], [1, 1, 1] ) + } + + /** + * 设置当前物体往经纬度和高度方向的移动 + * @param object + * @param lnglat + * @param altitude + */ + public applyObjectLngLat(object: Object3D, lnglat: ILngLat, altitude = 0) { + let positionMatrix = this.getTranslateMatrix(lnglat, altitude) + object.applyMatrix4(positionMatrix) + } + + /** + * 设置物体当前的经纬度和高度 + * @param object + * @param lnglat + * @param altitude + */ + public setObjectLngLat(object: Object3D, lnglat: ILngLat, altitude = 0) { + // @ts-ignore + let [x, y] = this.mapService?.lngLatToCoord(lnglat) + // @ts-ignore + // console.log(this.mapService?.lngLatToCoord(lnglat)) + // if(x && y) { + // console.log('------') + object.position.set(x, y, altitude) + // } + } + + public getObjectLngLat(object: Object3D) { + // let coord = [object.position.x, object.position.y]; + // // @ts-ignore + // return this.mapService.coordToLngLat(coord); + return [0,0] as ILngLat + } + public buildModels() { + // @ts-ignore this.threeRenderService = this.getContainer().get( ThreeRenderServiceType, ); diff --git a/packages/three/src/index.ts b/packages/three/src/index.ts index eeb2447453..8ac01a9c8d 100644 --- a/packages/three/src/index.ts +++ b/packages/three/src/index.ts @@ -1,3 +1,8 @@ import ThreeLayer from './core/baseLayer'; import ThreeRender from './core/threeRender'; -export { ThreeLayer, ThreeRender }; +import { IThreeJSLayer, ILngLat } from './core/IThreeJSLayer'; +import { + + Object3D + } from 'three'; +export { ThreeLayer, ThreeRender, IThreeJSLayer, ILngLat, Object3D }; diff --git a/stories/3D_Model/Components/amap2_three.tsx b/stories/3D_Model/Components/amap2_three.tsx index bb55abd1a2..efe34cdc8f 100644 --- a/stories/3D_Model/Components/amap2_three.tsx +++ b/stories/3D_Model/Components/amap2_three.tsx @@ -1,6 +1,6 @@ import { Scene } from '@antv/l7'; import { GaodeMap, GaodeMapV2, Mapbox } from '@antv/l7-maps'; -import { ThreeLayer, ThreeRender } from '@antv/l7-three'; +import { ThreeLayer, ThreeRender, ILngLat, Object3D } from '@antv/l7-three'; import * as React from 'react'; // import { DirectionalLight, Scene as ThreeScene } from 'three'; import * as THREE from 'three'; @@ -27,7 +27,7 @@ export default class GlTFThreeJSDemo extends React.Component { center: [111.4453125, 32.84267363195431], pitch: 45, rotation: 30, - zoom: 15, + zoom: 13, }), }); this.scene = scene; @@ -37,10 +37,21 @@ export default class GlTFThreeJSDemo extends React.Component { enableMultiPassRenderer: false, onAddMeshes: (threeScene: THREE.Scene, layer: ThreeLayer) => { threeScene.add(new THREE.AmbientLight(0xffffff)); + const sunlight = new THREE.DirectionalLight(0xffffff, 0.25); sunlight.position.set(0, 80000000, 100000000); sunlight.matrixWorldNeedsUpdate = true; threeScene.add(sunlight); + + // threeScene.applyMatrix4( + // layer.getModelMatrix( + // [111.4453125, 32.84267363195431], // 经纬度坐标 + // 0, // 高度,单位米/ + // [Math.PI / 2, -Math.PI, 0], // 沿 XYZ 轴旋转角度 + // [100, 100, 100], // 沿 XYZ 轴缩放比例 + // ), + // ) + // 使用 Three.js glTFLoader 加载模型 const loader = new GLTFLoader(); loader.load( @@ -52,37 +63,22 @@ export default class GlTFThreeJSDemo extends React.Component { // 'https://gw.alipayobjects.com/os/antvdemo/assets/gltf/man/CesiumMan.gltf', 'https://gw.alipayobjects.com/os/bmw-prod/3ca0a546-92d8-4ba0-a89c-017c218d5bea.gltf', (gltf) => { - // console.log(gltf) - const gltfScene = gltf.scene; - // gltfScene.rotation.set(90, 90, 0) + const model: Object3D = gltf.scene; + layer.getSource().data.dataArray.forEach(({ coordinates }) => { - const gltfScene = gltf.scene; - - gltfScene.scale.set(10, 10, 10); - // gltfScene.applyMatrix4( - // // 生成模型矩阵 - // layer.getModelMatrix( - // [coordinates[0], coordinates[1]], // 经纬度坐标 - // 0, // 高度,单位米/ - // [Math.PI / 2, -Math.PI, 0], // 沿 XYZ 轴旋转角度 - // [100, 100, 100], // 沿 XYZ 轴缩放比例 - // ), - // ); - - // gltfScene.applyMatrix4( - // // 生成模型矩阵 - // layer.getModelMatrix( - // // [coordinates[0], coordinates[1]], // 经纬度坐标 - // [0, 0], // 经纬度坐标 - // 0, // 高度,单位米/ - // [Math.PI / 2, -Math.PI, 0], // 沿 XYZ 轴旋转角度 - // [10000, 10000, 10000], // 沿 XYZ 轴缩放比例 - // ), - // ); + model.applyMatrix4( + // 生成模型矩阵 + layer.getModelMatrix( + [coordinates[0], coordinates[1]], // 经纬度坐标 + 0, // 高度,单位米/ + [Math.PI / 2, -Math.PI, 0], // 沿 XYZ 轴旋转角度 + [100, 100, 100], // 沿 XYZ 轴缩放比例 + ), + ); const animations = gltf.animations; if (animations && animations.length) { - const mixer = new THREE.AnimationMixer(gltfScene); + const mixer = new THREE.AnimationMixer(model); // @ts-ignore // for (let i = 0; i < 1; i++) { const animation = animations[2]; @@ -97,11 +93,27 @@ export default class GlTFThreeJSDemo extends React.Component { layer.addAnimateMixer(mixer); } - // 向场景中添加模型 - // threeScene.add(gltfScene); }); + // 向场景中添加模型 + threeScene.add(model); + + let lnglat = [121.107, 30.267069] as [number, number] + let altitude = 0 + let center = scene.getCenter() + // layer.setObjectLngLat(model, lnglat, altitude) + // console.log() + // layer.setObjectLngLat(model, [center.lng + 0.05, center.lat] as ILngLat, 0) + // layer.setObjectLngLat(model, [center.lng + 0.05, center.lat] as ILngLat, 0) + + layer.setObjectLngLat(model, [center.lng + 0.05, center.lat] as ILngLat, 0) + + let t = 0 + setInterval(() => { + t += 0.01 + layer.setObjectLngLat(model, [center.lng, center.lat + Math.sin(t) * 0.1] as ILngLat, 0) + // layer.setObjectLngLat(model, [center.lng + 0.2, center.lat], 0) + }, 16) - threeScene.add(gltfScene); // 重绘图层 layer.render(); }, @@ -117,6 +129,7 @@ export default class GlTFThreeJSDemo extends React.Component { geometry: { type: 'Point', coordinates: [111.4453125, 32.84267363195431], + // coordinates: [121.107, 30.267069], // 该坐标点在钱塘江入海口附近 }, }, ], diff --git a/stories/3D_Model/Components/amap_three.tsx b/stories/3D_Model/Components/amap_three.tsx index c63957acd3..9940b04bca 100644 --- a/stories/3D_Model/Components/amap_three.tsx +++ b/stories/3D_Model/Components/amap_three.tsx @@ -1,6 +1,6 @@ import { Scene } from '@antv/l7'; import { GaodeMap, Mapbox } from '@antv/l7-maps'; -import { ThreeLayer, ThreeRender } from '@antv/l7-three'; +import { ThreeLayer, ThreeRender, ILngLat } from '@antv/l7-three'; import * as React from 'react'; // import { DirectionalLight, Scene as ThreeScene } from 'three'; import * as THREE from 'three'; @@ -41,6 +41,16 @@ export default class GlTFThreeJSDemo extends React.Component { sunlight.position.set(0, 80000000, 100000000); sunlight.matrixWorldNeedsUpdate = true; threeScene.add(sunlight); + + + // threeScene.applyMatrix4( + // layer.getModelMatrix( + // [111.4453125, 32.84267363195431], // 经纬度坐标 + // 0, // 高度,单位米/ + // [Math.PI / 2, -Math.PI, 0], // 沿 XYZ 轴旋转角度 + // [1, 1, 1], // 沿 XYZ 轴缩放比例 + // ), + // ) // 使用 Three.js glTFLoader 加载模型 const loader = new GLTFLoader(); loader.load( @@ -61,7 +71,7 @@ export default class GlTFThreeJSDemo extends React.Component { [coordinates[0], coordinates[1]], // 经纬度坐标 0, // 高度,单位米/ [Math.PI / 2, -Math.PI, 0], // 沿 XYZ 轴旋转角度 - [100, 100, 100], // 沿 XYZ 轴缩放比例 + [1000, 1000, 1000], // 沿 XYZ 轴缩放比例 ), ); const animations = gltf.animations; @@ -80,6 +90,18 @@ export default class GlTFThreeJSDemo extends React.Component { // } layer.addAnimateMixer(mixer); } + // console.log(gltfScene.position) + let center = scene.getCenter() + console.log(center) + console.log(layer.getObjectLngLat(gltfScene)) + // layer.setObjectLngLat(gltfScene, [center.lng + 0.05, center.lat] as ILngLat, 0) + // layer.setObjectLngLat(gltfScene, [center.lng, center.lat] as ILngLat, 0) + let t = 0 + setInterval(() => { + t += 0.01 + layer.setObjectLngLat(gltfScene, [center.lng, center.lat + Math.sin(t) * 0.1] as ILngLat, 0) + // layer.setObjectLngLat(model, [center.lng + 0.2, center.lat], 0) + }, 16) // 向场景中添加模型 threeScene.add(gltfScene); @@ -98,7 +120,7 @@ export default class GlTFThreeJSDemo extends React.Component { properties: {}, geometry: { type: 'Point', - coordinates: [111.4453125, 32.84267363195431], + coordinates: [111.4453125, 32.84267363195431] }, }, ], diff --git a/stories/3D_Model/Components/mapbox_three.tsx b/stories/3D_Model/Components/mapbox_three.tsx index 5d07990def..9f217da74e 100644 --- a/stories/3D_Model/Components/mapbox_three.tsx +++ b/stories/3D_Model/Components/mapbox_three.tsx @@ -1,6 +1,6 @@ import { PolygonLayer, Scene } from '@antv/l7'; import { GaodeMap, Mapbox } from '@antv/l7-maps'; -import { ThreeLayer, ThreeRender } from '@antv/l7-three'; +import { ThreeLayer, ThreeRender, ILngLat } from '@antv/l7-three'; import * as React from 'react'; // import { DirectionalLight, Scene as ThreeScene } from 'three'; import * as THREE from 'three'; @@ -73,8 +73,9 @@ export default class GlTFThreeJSDemo extends React.Component { // 'https://gw.alipayobjects.com/os/bmw-prod/3ca0a546-92d8-4ba0-a89c-017c218d5bea.gltf', (gltf) => { // 根据 GeoJSON 数据放置模型 + const gltfScene = gltf.scene.clone(); layer.getSource().data.dataArray.forEach(({ coordinates }) => { - const gltfScene = gltf.scene.clone(); + gltfScene.applyMatrix4( // 生成模型矩阵 layer.getModelMatrix( @@ -105,6 +106,20 @@ export default class GlTFThreeJSDemo extends React.Component { // 向场景中添加模型 threeScene.add(gltfScene); }); + + let center = scene.getCenter() + console.log(center) + console.log(layer.getObjectLngLat(gltfScene)) + // layer.setObjectLngLat(gltfScene, [center.lng + 0.05, center.lat] as ILngLat, 0) + + // let t = 0 + // setInterval(() => { + // t += 0.01 + // layer.setObjectLngLat(gltfScene, [center.lng, center.lat + Math.sin(t) * 0.1] as ILngLat, 0) + // // layer.setObjectLngLat(model, [center.lng + 0.2, center.lat], 0) + // }, 16) + + // 重绘图层 layer.render(); }, From f29d0c6cc202c69b9dc43a1221c8b599a35e2447 Mon Sep 17 00:00:00 2001 From: 2912401452 <2912401452@qq.com> Date: Sat, 18 Sep 2021 16:04:37 +0800 Subject: [PATCH 3/5] style: lint style --- packages/maps/src/amap/map.ts | 4 +- packages/maps/src/amap2/map.ts | 3 +- packages/maps/src/mapbox/map.ts | 6 +-- packages/three/src/core/IThreeJSLayer.ts | 10 ++--- packages/three/src/core/baseLayer.ts | 39 ++++++++++---------- packages/three/src/index.ts | 7 +--- stories/3D_Model/Components/amap2_three.tsx | 27 +++++++++----- stories/3D_Model/Components/amap_three.tsx | 21 ++++++----- stories/3D_Model/Components/mapbox_three.tsx | 8 ++-- 9 files changed, 62 insertions(+), 63 deletions(-) diff --git a/packages/maps/src/amap/map.ts b/packages/maps/src/amap/map.ts index 68b59e357f..dee66c084f 100644 --- a/packages/maps/src/amap/map.ts +++ b/packages/maps/src/amap/map.ts @@ -277,8 +277,8 @@ export default class AMapService public lngLatToCoord(lnglat: [number, number]): any { // @ts-ignore - let { x, y } = this.map.lngLatToGeodeticCoord(lnglat) - return [x, -y] + const { x, y } = this.map.lngLatToGeodeticCoord(lnglat); + return [x, -y]; } public lngLatToMercator( diff --git a/packages/maps/src/amap2/map.ts b/packages/maps/src/amap2/map.ts index f9155490e3..664694fe5d 100644 --- a/packages/maps/src/amap2/map.ts +++ b/packages/maps/src/amap2/map.ts @@ -370,10 +370,9 @@ export default class AMapService scale: [number, number, number] = [1, 1, 1], origin: IMercator = { x: 0, y: 0, z: 0 }, ): number[] { - // const flat = this.viewport.projectFlat(lnglat); // @ts-ignore - const flat = this.map.customCoords.lngLatToCoord(lnglat) + const flat = this.map.customCoords.lngLatToCoord(lnglat); // @ts-ignore const modelMatrix = mat4.create(); diff --git a/packages/maps/src/mapbox/map.ts b/packages/maps/src/mapbox/map.ts index 7acae87b6f..46b1296c97 100644 --- a/packages/maps/src/mapbox/map.ts +++ b/packages/maps/src/mapbox/map.ts @@ -239,12 +239,12 @@ export default class MapboxService /** * 将经纬度转成墨卡托坐标 - * @param lnglat - * @returns + * @param lnglat + * @returns */ public lngLatToCoord(lnglat: [number, number]) { // @ts-ignore - let { x, y } = this.lngLatToMercator(lnglat, 0); + const { x, y } = this.lngLatToMercator(lnglat, 0); return [x, y] as [number, number]; } diff --git a/packages/three/src/core/IThreeJSLayer.ts b/packages/three/src/core/IThreeJSLayer.ts index a0bbca5b48..702cdb0710 100644 --- a/packages/three/src/core/IThreeJSLayer.ts +++ b/packages/three/src/core/IThreeJSLayer.ts @@ -1,11 +1,7 @@ import { ILayer } from '@antv/l7'; -import { - AnimationMixer, - Matrix4, - Object3D - } from 'three'; +import { AnimationMixer, Matrix4, Object3D } from 'three'; -export type ILngLat = [number, number] +export type ILngLat = [number, number]; export interface IThreeJSLayer extends ILayer { // 获取对应地图的经纬度模型矩阵 @@ -30,4 +26,4 @@ export interface IThreeJSLayer extends ILayer { // 增加加载模型的动画混合器 addAnimateMixer(mixer: AnimationMixer): void; -} \ No newline at end of file +} diff --git a/packages/three/src/core/baseLayer.ts b/packages/three/src/core/baseLayer.ts index 757df65af3..40b6feb9bc 100644 --- a/packages/three/src/core/baseLayer.ts +++ b/packages/three/src/core/baseLayer.ts @@ -3,17 +3,17 @@ import { AnimationMixer, Camera, Matrix4, + Object3D, PCFSoftShadowMap, PerspectiveCamera, Scene, WebGLRenderer, - Object3D } from 'three'; +import { ILngLat, IThreeJSLayer } from './IThreeJSLayer'; import { IThreeRenderService, ThreeRenderServiceType, } from './threeRenderService'; -import { IThreeJSLayer, ILngLat } from './IThreeJSLayer' const DEG2RAD = Math.PI / 180; export default class ThreeJSLayer extends BaseLayer<{ @@ -29,7 +29,6 @@ export default class ThreeJSLayer // 地图中点墨卡托坐标 private center: IMercator; - /** * 根据数据计算对应地图的模型矩阵 不同地图主要是点位偏移不同 */ @@ -52,39 +51,39 @@ export default class ThreeJSLayer /** * 获取平移矩阵 - * @param lnglat - * @param altitude - * @returns + * @param lnglat + * @param altitude + * @returns */ - public getTranslateMatrix( lnglat: ILngLat, altitude: number = 0,) { - return this.getModelMatrix( lnglat, altitude, [0, 0, 0], [1, 1, 1] ) + public getTranslateMatrix(lnglat: ILngLat, altitude: number = 0) { + return this.getModelMatrix(lnglat, altitude, [0, 0, 0], [1, 1, 1]); } /** * 设置当前物体往经纬度和高度方向的移动 - * @param object - * @param lnglat - * @param altitude + * @param object + * @param lnglat + * @param altitude */ public applyObjectLngLat(object: Object3D, lnglat: ILngLat, altitude = 0) { - let positionMatrix = this.getTranslateMatrix(lnglat, altitude) - object.applyMatrix4(positionMatrix) + const positionMatrix = this.getTranslateMatrix(lnglat, altitude); + object.applyMatrix4(positionMatrix); } /** * 设置物体当前的经纬度和高度 - * @param object - * @param lnglat - * @param altitude + * @param object + * @param lnglat + * @param altitude */ public setObjectLngLat(object: Object3D, lnglat: ILngLat, altitude = 0) { // @ts-ignore - let [x, y] = this.mapService?.lngLatToCoord(lnglat) + const [x, y] = this.mapService?.lngLatToCoord(lnglat); // @ts-ignore // console.log(this.mapService?.lngLatToCoord(lnglat)) // if(x && y) { - // console.log('------') - object.position.set(x, y, altitude) + // console.log('------') + object.position.set(x, y, altitude); // } } @@ -92,7 +91,7 @@ export default class ThreeJSLayer // let coord = [object.position.x, object.position.y]; // // @ts-ignore // return this.mapService.coordToLngLat(coord); - return [0,0] as ILngLat + return [0, 0] as ILngLat; } public buildModels() { diff --git a/packages/three/src/index.ts b/packages/three/src/index.ts index 8ac01a9c8d..6eb46c17fc 100644 --- a/packages/three/src/index.ts +++ b/packages/three/src/index.ts @@ -1,8 +1,5 @@ +import { Object3D } from 'three'; import ThreeLayer from './core/baseLayer'; +import { ILngLat, IThreeJSLayer } from './core/IThreeJSLayer'; import ThreeRender from './core/threeRender'; -import { IThreeJSLayer, ILngLat } from './core/IThreeJSLayer'; -import { - - Object3D - } from 'three'; export { ThreeLayer, ThreeRender, IThreeJSLayer, ILngLat, Object3D }; diff --git a/stories/3D_Model/Components/amap2_three.tsx b/stories/3D_Model/Components/amap2_three.tsx index efe34cdc8f..bbc6a85088 100644 --- a/stories/3D_Model/Components/amap2_three.tsx +++ b/stories/3D_Model/Components/amap2_three.tsx @@ -37,7 +37,7 @@ export default class GlTFThreeJSDemo extends React.Component { enableMultiPassRenderer: false, onAddMeshes: (threeScene: THREE.Scene, layer: ThreeLayer) => { threeScene.add(new THREE.AmbientLight(0xffffff)); - + const sunlight = new THREE.DirectionalLight(0xffffff, 0.25); sunlight.position.set(0, 80000000, 100000000); sunlight.matrixWorldNeedsUpdate = true; @@ -92,27 +92,34 @@ export default class GlTFThreeJSDemo extends React.Component { // } layer.addAnimateMixer(mixer); } - }); // 向场景中添加模型 threeScene.add(model); - let lnglat = [121.107, 30.267069] as [number, number] - let altitude = 0 - let center = scene.getCenter() + let lnglat = [121.107, 30.267069] as [number, number]; + let altitude = 0; + let center = scene.getCenter(); // layer.setObjectLngLat(model, lnglat, altitude) // console.log() // layer.setObjectLngLat(model, [center.lng + 0.05, center.lat] as ILngLat, 0) // layer.setObjectLngLat(model, [center.lng + 0.05, center.lat] as ILngLat, 0) - layer.setObjectLngLat(model, [center.lng + 0.05, center.lat] as ILngLat, 0) + layer.setObjectLngLat( + model, + [center.lng + 0.05, center.lat] as ILngLat, + 0, + ); - let t = 0 + let t = 0; setInterval(() => { - t += 0.01 - layer.setObjectLngLat(model, [center.lng, center.lat + Math.sin(t) * 0.1] as ILngLat, 0) + t += 0.01; + layer.setObjectLngLat( + model, + [center.lng, center.lat + Math.sin(t) * 0.1] as ILngLat, + 0, + ); // layer.setObjectLngLat(model, [center.lng + 0.2, center.lat], 0) - }, 16) + }, 16); // 重绘图层 layer.render(); diff --git a/stories/3D_Model/Components/amap_three.tsx b/stories/3D_Model/Components/amap_three.tsx index 9940b04bca..b2ea90f09f 100644 --- a/stories/3D_Model/Components/amap_three.tsx +++ b/stories/3D_Model/Components/amap_three.tsx @@ -42,7 +42,6 @@ export default class GlTFThreeJSDemo extends React.Component { sunlight.matrixWorldNeedsUpdate = true; threeScene.add(sunlight); - // threeScene.applyMatrix4( // layer.getModelMatrix( // [111.4453125, 32.84267363195431], // 经纬度坐标 @@ -91,17 +90,21 @@ export default class GlTFThreeJSDemo extends React.Component { layer.addAnimateMixer(mixer); } // console.log(gltfScene.position) - let center = scene.getCenter() - console.log(center) - console.log(layer.getObjectLngLat(gltfScene)) + let center = scene.getCenter(); + console.log(center); + console.log(layer.getObjectLngLat(gltfScene)); // layer.setObjectLngLat(gltfScene, [center.lng + 0.05, center.lat] as ILngLat, 0) // layer.setObjectLngLat(gltfScene, [center.lng, center.lat] as ILngLat, 0) - let t = 0 + let t = 0; setInterval(() => { - t += 0.01 - layer.setObjectLngLat(gltfScene, [center.lng, center.lat + Math.sin(t) * 0.1] as ILngLat, 0) + t += 0.01; + layer.setObjectLngLat( + gltfScene, + [center.lng, center.lat + Math.sin(t) * 0.1] as ILngLat, + 0, + ); // layer.setObjectLngLat(model, [center.lng + 0.2, center.lat], 0) - }, 16) + }, 16); // 向场景中添加模型 threeScene.add(gltfScene); @@ -120,7 +123,7 @@ export default class GlTFThreeJSDemo extends React.Component { properties: {}, geometry: { type: 'Point', - coordinates: [111.4453125, 32.84267363195431] + coordinates: [111.4453125, 32.84267363195431], }, }, ], diff --git a/stories/3D_Model/Components/mapbox_three.tsx b/stories/3D_Model/Components/mapbox_three.tsx index 9f217da74e..b4b5306562 100644 --- a/stories/3D_Model/Components/mapbox_three.tsx +++ b/stories/3D_Model/Components/mapbox_three.tsx @@ -75,7 +75,6 @@ export default class GlTFThreeJSDemo extends React.Component { // 根据 GeoJSON 数据放置模型 const gltfScene = gltf.scene.clone(); layer.getSource().data.dataArray.forEach(({ coordinates }) => { - gltfScene.applyMatrix4( // 生成模型矩阵 layer.getModelMatrix( @@ -107,9 +106,9 @@ export default class GlTFThreeJSDemo extends React.Component { threeScene.add(gltfScene); }); - let center = scene.getCenter() - console.log(center) - console.log(layer.getObjectLngLat(gltfScene)) + let center = scene.getCenter(); + console.log(center); + console.log(layer.getObjectLngLat(gltfScene)); // layer.setObjectLngLat(gltfScene, [center.lng + 0.05, center.lat] as ILngLat, 0) // let t = 0 @@ -119,7 +118,6 @@ export default class GlTFThreeJSDemo extends React.Component { // // layer.setObjectLngLat(model, [center.lng + 0.2, center.lat], 0) // }, 16) - // 重绘图层 layer.render(); }, From 9824f4d0a36a88afa3bdc63ecc2840d8f28efd71 Mon Sep 17 00:00:00 2001 From: 2912401452 <2912401452@qq.com> Date: Wed, 22 Sep 2021 16:57:05 +0800 Subject: [PATCH 4/5] =?UTF-8?q?feat:=20=E5=AE=8C=E5=96=84=E5=AF=B9=20three?= =?UTF-8?q?js=20=E7=9A=84=E5=85=BC=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 1 + packages/maps/src/mapbox/map.ts | 4 +- packages/three/src/core/baseLayer.ts | 57 ++++- stories/3D_Model/Components/amap2_three.tsx | 22 +- stories/3D_Model/Components/amap_three.tsx | 40 ++-- stories/3D_Model/Components/mapbox_three.tsx | 214 +++++++++++++++++-- stories/3D_Model/Components/threeRender.tsx | 55 ++--- 7 files changed, 303 insertions(+), 90 deletions(-) diff --git a/package.json b/package.json index 8a093da63a..5ef325b786 100644 --- a/package.json +++ b/package.json @@ -88,6 +88,7 @@ "lint-staged": "^9.2.4", "node-sass": "^4.12.0", "npm-run-all": "^4.1.5", + "popmotion": "^9.4.2", "postcss": "^7.0.18", "postcss-plugin": "^1.0.0", "postcss-url": "^8.0.0", diff --git a/packages/maps/src/mapbox/map.ts b/packages/maps/src/mapbox/map.ts index 46b1296c97..511c1c4726 100644 --- a/packages/maps/src/mapbox/map.ts +++ b/packages/maps/src/mapbox/map.ts @@ -242,10 +242,10 @@ export default class MapboxService * @param lnglat * @returns */ - public lngLatToCoord(lnglat: [number, number]) { + public lngLatToCoord(lnglat: [number, number],origin: IMercator = { x: 0, y: 0, z: 0 }) { // @ts-ignore const { x, y } = this.lngLatToMercator(lnglat, 0); - return [x, y] as [number, number]; + return [x - origin.x, y - origin.y] as [number, number]; } public lngLatToMercator( diff --git a/packages/three/src/core/baseLayer.ts b/packages/three/src/core/baseLayer.ts index 40b6feb9bc..e92c1189d4 100644 --- a/packages/three/src/core/baseLayer.ts +++ b/packages/three/src/core/baseLayer.ts @@ -3,6 +3,7 @@ import { AnimationMixer, Camera, Matrix4, + Vector3, Object3D, PCFSoftShadowMap, PerspectiveCamera, @@ -78,22 +79,60 @@ export default class ThreeJSLayer */ public setObjectLngLat(object: Object3D, lnglat: ILngLat, altitude = 0) { // @ts-ignore - const [x, y] = this.mapService?.lngLatToCoord(lnglat); - // @ts-ignore - // console.log(this.mapService?.lngLatToCoord(lnglat)) - // if(x && y) { - // console.log('------') + const [x, y] = this.lnglatToCoord(lnglat); object.position.set(x, y, altitude); - // } } + /** + * 将经纬度转为 three 世界坐标 + * @param lnglat + * @returns + */ + public lnglatToCoord(lnglat: ILngLat) { + // @ts-ignore + const [x, y] = this.mapService?.lngLatToCoord(lnglat, this.threeRenderService.center); + return [x, y]; + } + + /** + * 获取 + * @param object + * @returns + */ public getObjectLngLat(object: Object3D) { - // let coord = [object.position.x, object.position.y]; - // // @ts-ignore - // return this.mapService.coordToLngLat(coord); + let coord = [object.position.x, object.position.y]; return [0, 0] as ILngLat; } + /** + * 设置网格适配到地图坐标系 + * @param object + */ + public adjustMeshToMap(object: Object3D) { + object.up = new Vector3(0, 0, 1) + let defaultLngLat = this.mapService.getCenter() + let modelMatrix = this.getModelMatrix( + [defaultLngLat.lng, defaultLngLat.lat], // 经纬度坐标 + 0, // 高度,单位米/ + [Math.PI / 2, -Math.PI, 0], // 沿 XYZ 轴旋转角度 + [1, 1, 1], // 沿 XYZ 轴缩放比例 + ) + object.applyMatrix4(modelMatrix); + } + + /** + * 设置网格的缩放 (主要是抹平 mapbox 底图时的差异,若是高德底图则可以直接设置网格的 scale 属性/方法) + * @param object + * @param x + * @param y + * @param z + */ + public setMeshScale(object: Object3D, x: number = 1, y: number = 1, z: number = 1) { + let scaleMatrix = new Matrix4() + scaleMatrix.scale(new Vector3(x, y, z)) + object.applyMatrix4(scaleMatrix) + } + public buildModels() { // @ts-ignore this.threeRenderService = this.getContainer().get( diff --git a/stories/3D_Model/Components/amap2_three.tsx b/stories/3D_Model/Components/amap2_three.tsx index bbc6a85088..1c188a4343 100644 --- a/stories/3D_Model/Components/amap2_three.tsx +++ b/stories/3D_Model/Components/amap2_three.tsx @@ -43,15 +43,6 @@ export default class GlTFThreeJSDemo extends React.Component { sunlight.matrixWorldNeedsUpdate = true; threeScene.add(sunlight); - // threeScene.applyMatrix4( - // layer.getModelMatrix( - // [111.4453125, 32.84267363195431], // 经纬度坐标 - // 0, // 高度,单位米/ - // [Math.PI / 2, -Math.PI, 0], // 沿 XYZ 轴旋转角度 - // [100, 100, 100], // 沿 XYZ 轴缩放比例 - // ), - // ) - // 使用 Three.js glTFLoader 加载模型 const loader = new GLTFLoader(); loader.load( @@ -66,15 +57,10 @@ export default class GlTFThreeJSDemo extends React.Component { const model: Object3D = gltf.scene; layer.getSource().data.dataArray.forEach(({ coordinates }) => { - model.applyMatrix4( - // 生成模型矩阵 - layer.getModelMatrix( - [coordinates[0], coordinates[1]], // 经纬度坐标 - 0, // 高度,单位米/ - [Math.PI / 2, -Math.PI, 0], // 沿 XYZ 轴旋转角度 - [100, 100, 100], // 沿 XYZ 轴缩放比例 - ), - ); + + layer.adjustMeshToMap(model) + // model.scale.set(100, 100, 100) + layer.setMeshScale(model, 100, 100, 100) const animations = gltf.animations; if (animations && animations.length) { diff --git a/stories/3D_Model/Components/amap_three.tsx b/stories/3D_Model/Components/amap_three.tsx index b2ea90f09f..cffe9c23fc 100644 --- a/stories/3D_Model/Components/amap_three.tsx +++ b/stories/3D_Model/Components/amap_three.tsx @@ -42,14 +42,14 @@ export default class GlTFThreeJSDemo extends React.Component { sunlight.matrixWorldNeedsUpdate = true; threeScene.add(sunlight); - // threeScene.applyMatrix4( - // layer.getModelMatrix( - // [111.4453125, 32.84267363195431], // 经纬度坐标 - // 0, // 高度,单位米/ - // [Math.PI / 2, -Math.PI, 0], // 沿 XYZ 轴旋转角度 - // [1, 1, 1], // 沿 XYZ 轴缩放比例 - // ), - // ) + let center = scene.getCenter() + + let cubeGeometry = new THREE.BoxBufferGeometry(10000, 10000, 10000) + let cubeMaterial = new THREE.MeshNormalMaterial() + let cube = new THREE.Mesh(cubeGeometry, cubeMaterial) + layer.setObjectLngLat(cube, [center.lng + 0.05, center.lat] as ILngLat, 0) + threeScene.add(cube) + // 使用 Three.js glTFLoader 加载模型 const loader = new GLTFLoader(); loader.load( @@ -64,15 +64,15 @@ export default class GlTFThreeJSDemo extends React.Component { // 根据 GeoJSON 数据放置模型 layer.getSource().data.dataArray.forEach(({ coordinates }) => { const gltfScene = gltf.scene; - gltfScene.applyMatrix4( - // 生成模型矩阵 - layer.getModelMatrix( - [coordinates[0], coordinates[1]], // 经纬度坐标 - 0, // 高度,单位米/ - [Math.PI / 2, -Math.PI, 0], // 沿 XYZ 轴旋转角度 - [1000, 1000, 1000], // 沿 XYZ 轴缩放比例 - ), - ); + + layer.adjustMeshToMap(gltfScene) + // gltfScene.scale.set(1000, 1000, 1000) + layer.setMeshScale(gltfScene, 1000, 1000, 1000) + + + + layer.setObjectLngLat(gltfScene, [coordinates[0] + 0.02, coordinates[1]], 0) + const animations = gltf.animations; if (animations && animations.length) { const mixer = new THREE.AnimationMixer(gltfScene); @@ -89,12 +89,7 @@ export default class GlTFThreeJSDemo extends React.Component { // } layer.addAnimateMixer(mixer); } - // console.log(gltfScene.position) - let center = scene.getCenter(); - console.log(center); - console.log(layer.getObjectLngLat(gltfScene)); // layer.setObjectLngLat(gltfScene, [center.lng + 0.05, center.lat] as ILngLat, 0) - // layer.setObjectLngLat(gltfScene, [center.lng, center.lat] as ILngLat, 0) let t = 0; setInterval(() => { t += 0.01; @@ -103,7 +98,6 @@ export default class GlTFThreeJSDemo extends React.Component { [center.lng, center.lat + Math.sin(t) * 0.1] as ILngLat, 0, ); - // layer.setObjectLngLat(model, [center.lng + 0.2, center.lat], 0) }, 16); // 向场景中添加模型 diff --git a/stories/3D_Model/Components/mapbox_three.tsx b/stories/3D_Model/Components/mapbox_three.tsx index b4b5306562..6a4eec0346 100644 --- a/stories/3D_Model/Components/mapbox_three.tsx +++ b/stories/3D_Model/Components/mapbox_three.tsx @@ -6,6 +6,53 @@ import * as React from 'react'; import * as THREE from 'three'; // tslint:disable-next-line:no-submodule-imports import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'; +import { animate, easeInOut } from 'popmotion' +import { Object3D, Vector3 } from 'three'; + +let isTravel = false + +function travel(mesh: Object3D, path: Vector3[], duration: number,callback?: () => any) { + if (path.length < 2 || isTravel) return; + isTravel = true; + let startIndex = 0, len = path.length; + let currentP = path[0], nextP = path[1]; + let t = duration/len; + + move(currentP, nextP); + function move(currentP: Vector3, nextP: Vector3) { + animate({ + from: { + x: currentP.x, + y: currentP.y, + z: currentP.z, + }, + to: { + x: nextP.x, + y: nextP.y, + z: nextP.z, + }, + ease: easeInOut, + duration: t, + repeatType: 'loop', + onUpdate: (o) => { + mesh.position.set(o.x, o.y, o.z); + }, + onComplete: () => { + startIndex++; + if (startIndex < len - 1) { + let currentP = path[startIndex], + nextP = path[startIndex + 1]; + mesh.lookAt(nextP); + + move(currentP, nextP); + } else { + isTravel = false; + callback && callback(); + } + } + }) + } +} export default class GlTFThreeJSDemo extends React.Component { // @ts-ignore @@ -61,6 +108,147 @@ export default class GlTFThreeJSDemo extends React.Component { sunlight.position.set(0, 80000000, 100000000); sunlight.matrixWorldNeedsUpdate = true; threeScene.add(sunlight); + + let lineData: ILngLat[] = [ + [ + 116.71874999999999, + 26.745610382199022 + ], + [ + 117.3779296875, + 28.8831596093235 + ], + [ + 115.75195312499999, + 31.466153715024294 + ], + [ + 113.466796875, + 33.32134852669881 + ], + [ + 113.9501953125, + 35.85343961959182 + ], + [ + 115.400390625, + 38.272688535980976 + ], + [ + 116.5869140625, + 40.3130432088809 + ], + [ + 115.6201171875, + 42.261049162113856 + ], + [ + 112.236328125, + 42.94033923363181 + ], + [ + 109.3798828125, + 41.04621681452063 + ], + [ + 103.84277343749999, + 39.80853604144591 + ], + [ + 98.9208984375, + 39.842286020743394 + ], + [ + 95.2294921875, + 40.713955826286046 + ], + [ + 91.7138671875, + 39.87601941962116 + ], + [ + 90.8349609375, + 37.125286284966805 + ], + [ + 90.3076171875, + 35.88905007936091 + ], + [ + 90.703125, + 33.284619968887675 + ], + [ + 92.94433593749999, + 31.98944183792288 + ], + [ + 96.2841796875, + 32.21280106801518 + ], + [ + 98.87695312499999, + 32.0639555946604 + ], + [ + 102.919921875, + 28.459033019728043 + ], + [ + 107.9736328125, + 28.497660832963472 + ], + [ + 108.10546875, + 24.206889622398023 + ], + [ + 109.072265625, + 23.039297747769726 + ], + [ + 112.763671875, + 24.44714958973082 + ], + [ + 116.54296874999999, + 25.958044673317843 + ] + ] + + let lineCoordData = lineData.map((d: ILngLat) => { + return layer.lnglatToCoord(d) + }) + // console.log(lineCoordData) + + var material = new THREE.LineBasicMaterial({ + color: 0x0000ff + }); + + + + var rawPoints: THREE.Vector3[] = [] + lineCoordData.map(d => { + rawPoints.push(new THREE.Vector3(d[0], d[1], 0)) + }) + var curve = new THREE.CatmullRomCurve3(rawPoints); + var points = curve.getPoints( 200 ); + var geometry = new THREE.BufferGeometry().setFromPoints( points ); + + var material = new THREE.LineBasicMaterial( { color : 0xff0000 } ); + + + var line = new THREE.LineLoop( geometry, material ); + threeScene.add( line ); + + // console.log(line) + // animate({ + // from: 0, + // to: 100, + // duration: 3000, + // onUpdate: latest => console.log(latest) + // }) + // 使用 Three.js glTFLoader 加载模型 const loader = new GLTFLoader(); loader.load( @@ -75,15 +263,10 @@ export default class GlTFThreeJSDemo extends React.Component { // 根据 GeoJSON 数据放置模型 const gltfScene = gltf.scene.clone(); layer.getSource().data.dataArray.forEach(({ coordinates }) => { - gltfScene.applyMatrix4( - // 生成模型矩阵 - layer.getModelMatrix( - [coordinates[0], coordinates[1]], // 经纬度坐标 - 0, // 高度,单位米 - [Math.PI / 2, 0, 0], // 沿 XYZ 轴旋转角度 - [100000, 100000, 100000], // 沿 XYZ 轴缩放比例 - ), - ); + layer.adjustMeshToMap(gltfScene) + gltfScene.scale.set(500000, 500000, 500000) + + // gltfScene.rotation.y = Math.PI const animations = gltf.animations; if (animations && animations.length) { @@ -107,17 +290,22 @@ export default class GlTFThreeJSDemo extends React.Component { }); let center = scene.getCenter(); - console.log(center); - console.log(layer.getObjectLngLat(gltfScene)); // layer.setObjectLngLat(gltfScene, [center.lng + 0.05, center.lat] as ILngLat, 0) - // let t = 0 + // let t = 0 // setInterval(() => { // t += 0.01 - // layer.setObjectLngLat(gltfScene, [center.lng, center.lat + Math.sin(t) * 0.1] as ILngLat, 0) + // layer.setObjectLngLat(gltfScene, [center.lng, center.lat + Math.sin(t) * 10] as ILngLat, 0) // // layer.setObjectLngLat(model, [center.lng + 0.2, center.lat], 0) // }, 16) + // travel(gltfScene, points, 5000) + travelLoop() + function travelLoop() { + travel(gltfScene, points, 5000, () => { + travelLoop() + }) + } // 重绘图层 layer.render(); }, diff --git a/stories/3D_Model/Components/threeRender.tsx b/stories/3D_Model/Components/threeRender.tsx index 10eb823bee..a2be5f5c94 100644 --- a/stories/3D_Model/Components/threeRender.tsx +++ b/stories/3D_Model/Components/threeRender.tsx @@ -37,33 +37,28 @@ export default class GlTFThreeJSDemo extends React.Component { const response = await fetch( 'https://gw.alipayobjects.com/os/basement_prod/893d1d5f-11d9-45f3-8322-ee9140d288ae.json', ); - scene.addImage( - '00', - 'https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*Rq6tQ5b4_JMAAAAAAAAAAABkARQnAQ', - ); - scene.addImage( - '01', - 'https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*0D0SQ6AgkRMAAAAAAAAAAABkARQnAQ', - ); - scene.addImage( - '02', - 'https://gw.alipayobjects.com/zos/rmsportal/xZXhTxbglnuTmZEwqQrE.png', - ); const data = await response.json(); const imageLayer = new PointLayer() - .source(data, { + .source( + // [{ + // longitude: 120, + // latitude: 30 + // }] + data + , { parser: { type: 'json', x: 'longitude', y: 'latitude', }, }) - // .shape('name', ['00', '01', '02']) .shape('triangle') .color('red') .active(true) - .size(20); - scene.addLayer(imageLayer); + .size(20) + .animate(true) + // scene.addLayer(imageLayer); + const threeJSLayer = new ThreeLayer({ enableMultiPassRenderer: false, onAddMeshes: (threeScene: THREE.Scene, layer: ThreeLayer) => { @@ -73,6 +68,9 @@ export default class GlTFThreeJSDemo extends React.Component { sunlight.matrixWorldNeedsUpdate = true; threeScene.add(sunlight); // 使用 Three.js glTFLoader 加载模型 + + let center = scene.getCenter(); + const loader = new GLTFLoader(); loader.load( // 'https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Models/master/2.0/DamagedHelmet/glTF/DamagedHelmet.gltf', @@ -86,15 +84,10 @@ export default class GlTFThreeJSDemo extends React.Component { // 根据 GeoJSON 数据放置模型 layer.getSource().data.dataArray.forEach(({ coordinates }) => { const gltfScene = gltf.scene; - gltfScene.applyMatrix4( - // 生成模型矩阵 - layer.getModelMatrix( - [coordinates[0], coordinates[1]], // 经纬度坐标 - 0, // 高度,单位米/ - [Math.PI / 2, -Math.PI, 0], // 沿 XYZ 轴旋转角度 - [10, 10, 10], // 沿 XYZ 轴缩放比例 - ), - ); + + layer.adjustMeshToMap(gltfScene) + layer.setMeshScale(gltfScene, 10, 10, 10) + const animations = gltf.animations; if (animations && animations.length) { const mixer = new THREE.AnimationMixer(gltfScene); @@ -114,6 +107,18 @@ export default class GlTFThreeJSDemo extends React.Component { // 向场景中添加模型 threeScene.add(gltfScene); + + + // layer.setObjectLngLat(gltfScene, [120, 30], 0) + // @ts-ignore + // console.log(layer.mapService.lngLatToCoord([121.4, 31.258134])) + + // let t = 0 + // setInterval(() => { + // t += 0.01 + // layer.setObjectLngLat(gltfScene, [center.lng, center.lat + Math.sin(t) * 0.005] as ILngLat, 0) + // // layer.setObjectLngLat(model, [center.lng + 0.2, center.lat], 0) + // }, 16) }); // 重绘图层 layer.render(); From 4e7c4584a5e0cae414935a76c0594295675c4cd4 Mon Sep 17 00:00:00 2001 From: 2912401452 <2912401452@qq.com> Date: Wed, 22 Sep 2021 16:58:58 +0800 Subject: [PATCH 5/5] style: lint style --- packages/maps/src/mapbox/map.ts | 5 +- packages/three/src/core/baseLayer.ts | 49 +++-- stories/3D_Model/Components/amap2_three.tsx | 5 +- stories/3D_Model/Components/amap_three.tsx | 28 +-- stories/3D_Model/Components/mapbox_three.tsx | 194 ++++++------------- stories/3D_Model/Components/threeRender.tsx | 26 +-- 6 files changed, 125 insertions(+), 182 deletions(-) diff --git a/packages/maps/src/mapbox/map.ts b/packages/maps/src/mapbox/map.ts index 511c1c4726..f7d9875421 100644 --- a/packages/maps/src/mapbox/map.ts +++ b/packages/maps/src/mapbox/map.ts @@ -242,7 +242,10 @@ export default class MapboxService * @param lnglat * @returns */ - public lngLatToCoord(lnglat: [number, number],origin: IMercator = { x: 0, y: 0, z: 0 }) { + public lngLatToCoord( + lnglat: [number, number], + origin: IMercator = { x: 0, y: 0, z: 0 }, + ) { // @ts-ignore const { x, y } = this.lngLatToMercator(lnglat, 0); return [x - origin.x, y - origin.y] as [number, number]; diff --git a/packages/three/src/core/baseLayer.ts b/packages/three/src/core/baseLayer.ts index e92c1189d4..34a9dd5faa 100644 --- a/packages/three/src/core/baseLayer.ts +++ b/packages/three/src/core/baseLayer.ts @@ -3,11 +3,11 @@ import { AnimationMixer, Camera, Matrix4, - Vector3, Object3D, PCFSoftShadowMap, PerspectiveCamera, Scene, + Vector3, WebGLRenderer, } from 'three'; import { ILngLat, IThreeJSLayer } from './IThreeJSLayer'; @@ -85,52 +85,61 @@ export default class ThreeJSLayer /** * 将经纬度转为 three 世界坐标 - * @param lnglat - * @returns + * @param lnglat + * @returns */ public lnglatToCoord(lnglat: ILngLat) { // @ts-ignore - const [x, y] = this.mapService?.lngLatToCoord(lnglat, this.threeRenderService.center); + const [x, y] = this.mapService?.lngLatToCoord( + lnglat, + // @ts-ignore + this.threeRenderService.center, + ); return [x, y]; } /** * 获取 - * @param object - * @returns + * @param object + * @returns */ public getObjectLngLat(object: Object3D) { - let coord = [object.position.x, object.position.y]; + const coord = [object.position.x, object.position.y]; return [0, 0] as ILngLat; } /** * 设置网格适配到地图坐标系 - * @param object + * @param object */ public adjustMeshToMap(object: Object3D) { - object.up = new Vector3(0, 0, 1) - let defaultLngLat = this.mapService.getCenter() - let modelMatrix = this.getModelMatrix( + object.up = new Vector3(0, 0, 1); + const defaultLngLat = this.mapService.getCenter(); + const modelMatrix = this.getModelMatrix( [defaultLngLat.lng, defaultLngLat.lat], // 经纬度坐标 0, // 高度,单位米/ [Math.PI / 2, -Math.PI, 0], // 沿 XYZ 轴旋转角度 [1, 1, 1], // 沿 XYZ 轴缩放比例 - ) + ); object.applyMatrix4(modelMatrix); } /** * 设置网格的缩放 (主要是抹平 mapbox 底图时的差异,若是高德底图则可以直接设置网格的 scale 属性/方法) - * @param object - * @param x - * @param y - * @param z + * @param object + * @param x + * @param y + * @param z */ - public setMeshScale(object: Object3D, x: number = 1, y: number = 1, z: number = 1) { - let scaleMatrix = new Matrix4() - scaleMatrix.scale(new Vector3(x, y, z)) - object.applyMatrix4(scaleMatrix) + public setMeshScale( + object: Object3D, + x: number = 1, + y: number = 1, + z: number = 1, + ) { + const scaleMatrix = new Matrix4(); + scaleMatrix.scale(new Vector3(x, y, z)); + object.applyMatrix4(scaleMatrix); } public buildModels() { diff --git a/stories/3D_Model/Components/amap2_three.tsx b/stories/3D_Model/Components/amap2_three.tsx index 1c188a4343..fc4780dbd2 100644 --- a/stories/3D_Model/Components/amap2_three.tsx +++ b/stories/3D_Model/Components/amap2_three.tsx @@ -57,10 +57,9 @@ export default class GlTFThreeJSDemo extends React.Component { const model: Object3D = gltf.scene; layer.getSource().data.dataArray.forEach(({ coordinates }) => { - - layer.adjustMeshToMap(model) + layer.adjustMeshToMap(model); // model.scale.set(100, 100, 100) - layer.setMeshScale(model, 100, 100, 100) + layer.setMeshScale(model, 100, 100, 100); const animations = gltf.animations; if (animations && animations.length) { diff --git a/stories/3D_Model/Components/amap_three.tsx b/stories/3D_Model/Components/amap_three.tsx index cffe9c23fc..df466d718e 100644 --- a/stories/3D_Model/Components/amap_three.tsx +++ b/stories/3D_Model/Components/amap_three.tsx @@ -42,13 +42,17 @@ export default class GlTFThreeJSDemo extends React.Component { sunlight.matrixWorldNeedsUpdate = true; threeScene.add(sunlight); - let center = scene.getCenter() + let center = scene.getCenter(); - let cubeGeometry = new THREE.BoxBufferGeometry(10000, 10000, 10000) - let cubeMaterial = new THREE.MeshNormalMaterial() - let cube = new THREE.Mesh(cubeGeometry, cubeMaterial) - layer.setObjectLngLat(cube, [center.lng + 0.05, center.lat] as ILngLat, 0) - threeScene.add(cube) + let cubeGeometry = new THREE.BoxBufferGeometry(10000, 10000, 10000); + let cubeMaterial = new THREE.MeshNormalMaterial(); + let cube = new THREE.Mesh(cubeGeometry, cubeMaterial); + layer.setObjectLngLat( + cube, + [center.lng + 0.05, center.lat] as ILngLat, + 0, + ); + threeScene.add(cube); // 使用 Three.js glTFLoader 加载模型 const loader = new GLTFLoader(); @@ -65,13 +69,15 @@ export default class GlTFThreeJSDemo extends React.Component { layer.getSource().data.dataArray.forEach(({ coordinates }) => { const gltfScene = gltf.scene; - layer.adjustMeshToMap(gltfScene) + layer.adjustMeshToMap(gltfScene); // gltfScene.scale.set(1000, 1000, 1000) - layer.setMeshScale(gltfScene, 1000, 1000, 1000) + layer.setMeshScale(gltfScene, 1000, 1000, 1000); - - - layer.setObjectLngLat(gltfScene, [coordinates[0] + 0.02, coordinates[1]], 0) + layer.setObjectLngLat( + gltfScene, + [coordinates[0] + 0.02, coordinates[1]], + 0, + ); const animations = gltf.animations; if (animations && animations.length) { diff --git a/stories/3D_Model/Components/mapbox_three.tsx b/stories/3D_Model/Components/mapbox_three.tsx index 6a4eec0346..9336365d3e 100644 --- a/stories/3D_Model/Components/mapbox_three.tsx +++ b/stories/3D_Model/Components/mapbox_three.tsx @@ -6,17 +6,24 @@ import * as React from 'react'; import * as THREE from 'three'; // tslint:disable-next-line:no-submodule-imports import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'; -import { animate, easeInOut } from 'popmotion' +import { animate, easeInOut } from 'popmotion'; import { Object3D, Vector3 } from 'three'; -let isTravel = false +let isTravel = false; -function travel(mesh: Object3D, path: Vector3[], duration: number,callback?: () => any) { +function travel( + mesh: Object3D, + path: Vector3[], + duration: number, + callback?: () => any, +) { if (path.length < 2 || isTravel) return; isTravel = true; - let startIndex = 0, len = path.length; - let currentP = path[0], nextP = path[1]; - let t = duration/len; + let startIndex = 0, + len = path.length; + let currentP = path[0], + nextP = path[1]; + let t = duration / len; move(currentP, nextP); function move(currentP: Vector3, nextP: Vector3) { @@ -43,14 +50,14 @@ function travel(mesh: Object3D, path: Vector3[], duration: number,callback?: () let currentP = path[startIndex], nextP = path[startIndex + 1]; mesh.lookAt(nextP); - + move(currentP, nextP); } else { isTravel = false; callback && callback(); } - } - }) + }, + }); } } @@ -110,136 +117,55 @@ export default class GlTFThreeJSDemo extends React.Component { threeScene.add(sunlight); let lineData: ILngLat[] = [ - [ - 116.71874999999999, - 26.745610382199022 - ], - [ - 117.3779296875, - 28.8831596093235 - ], - [ - 115.75195312499999, - 31.466153715024294 - ], - [ - 113.466796875, - 33.32134852669881 - ], - [ - 113.9501953125, - 35.85343961959182 - ], - [ - 115.400390625, - 38.272688535980976 - ], - [ - 116.5869140625, - 40.3130432088809 - ], - [ - 115.6201171875, - 42.261049162113856 - ], - [ - 112.236328125, - 42.94033923363181 - ], - [ - 109.3798828125, - 41.04621681452063 - ], - [ - 103.84277343749999, - 39.80853604144591 - ], - [ - 98.9208984375, - 39.842286020743394 - ], - [ - 95.2294921875, - 40.713955826286046 - ], - [ - 91.7138671875, - 39.87601941962116 - ], - [ - 90.8349609375, - 37.125286284966805 - ], - [ - 90.3076171875, - 35.88905007936091 - ], - [ - 90.703125, - 33.284619968887675 - ], - [ - 92.94433593749999, - 31.98944183792288 - ], - [ - 96.2841796875, - 32.21280106801518 - ], - [ - 98.87695312499999, - 32.0639555946604 - ], - [ - 102.919921875, - 28.459033019728043 - ], - [ - 107.9736328125, - 28.497660832963472 - ], - [ - 108.10546875, - 24.206889622398023 - ], - [ - 109.072265625, - 23.039297747769726 - ], - [ - 112.763671875, - 24.44714958973082 - ], - [ - 116.54296874999999, - 25.958044673317843 - ] - ] + [116.71874999999999, 26.745610382199022], + [117.3779296875, 28.8831596093235], + [115.75195312499999, 31.466153715024294], + [113.466796875, 33.32134852669881], + [113.9501953125, 35.85343961959182], + [115.400390625, 38.272688535980976], + [116.5869140625, 40.3130432088809], + [115.6201171875, 42.261049162113856], + [112.236328125, 42.94033923363181], + [109.3798828125, 41.04621681452063], + [103.84277343749999, 39.80853604144591], + [98.9208984375, 39.842286020743394], + [95.2294921875, 40.713955826286046], + [91.7138671875, 39.87601941962116], + [90.8349609375, 37.125286284966805], + [90.3076171875, 35.88905007936091], + [90.703125, 33.284619968887675], + [92.94433593749999, 31.98944183792288], + [96.2841796875, 32.21280106801518], + [98.87695312499999, 32.0639555946604], + [102.919921875, 28.459033019728043], + [107.9736328125, 28.497660832963472], + [108.10546875, 24.206889622398023], + [109.072265625, 23.039297747769726], + [112.763671875, 24.44714958973082], + [116.54296874999999, 25.958044673317843], + ]; let lineCoordData = lineData.map((d: ILngLat) => { - return layer.lnglatToCoord(d) - }) + return layer.lnglatToCoord(d); + }); // console.log(lineCoordData) var material = new THREE.LineBasicMaterial({ - color: 0x0000ff + color: 0x0000ff, }); - - - var rawPoints: THREE.Vector3[] = [] - lineCoordData.map(d => { - rawPoints.push(new THREE.Vector3(d[0], d[1], 0)) - }) + var rawPoints: THREE.Vector3[] = []; + lineCoordData.map((d) => { + rawPoints.push(new THREE.Vector3(d[0], d[1], 0)); + }); var curve = new THREE.CatmullRomCurve3(rawPoints); - var points = curve.getPoints( 200 ); - var geometry = new THREE.BufferGeometry().setFromPoints( points ); + var points = curve.getPoints(200); + var geometry = new THREE.BufferGeometry().setFromPoints(points); - var material = new THREE.LineBasicMaterial( { color : 0xff0000 } ); + var material = new THREE.LineBasicMaterial({ color: 0xff0000 }); - - var line = new THREE.LineLoop( geometry, material ); - threeScene.add( line ); + var line = new THREE.LineLoop(geometry, material); + threeScene.add(line); // console.log(line) // animate({ @@ -263,8 +189,8 @@ export default class GlTFThreeJSDemo extends React.Component { // 根据 GeoJSON 数据放置模型 const gltfScene = gltf.scene.clone(); layer.getSource().data.dataArray.forEach(({ coordinates }) => { - layer.adjustMeshToMap(gltfScene) - gltfScene.scale.set(500000, 500000, 500000) + layer.adjustMeshToMap(gltfScene); + gltfScene.scale.set(500000, 500000, 500000); // gltfScene.rotation.y = Math.PI @@ -300,11 +226,11 @@ export default class GlTFThreeJSDemo extends React.Component { // }, 16) // travel(gltfScene, points, 5000) - travelLoop() + travelLoop(); function travelLoop() { travel(gltfScene, points, 5000, () => { - travelLoop() - }) + travelLoop(); + }); } // 重绘图层 layer.render(); diff --git a/stories/3D_Model/Components/threeRender.tsx b/stories/3D_Model/Components/threeRender.tsx index a2be5f5c94..40744b13c2 100644 --- a/stories/3D_Model/Components/threeRender.tsx +++ b/stories/3D_Model/Components/threeRender.tsx @@ -44,19 +44,20 @@ export default class GlTFThreeJSDemo extends React.Component { // longitude: 120, // latitude: 30 // }] - data - , { - parser: { - type: 'json', - x: 'longitude', - y: 'latitude', + data, + { + parser: { + type: 'json', + x: 'longitude', + y: 'latitude', + }, }, - }) + ) .shape('triangle') .color('red') .active(true) .size(20) - .animate(true) + .animate(true); // scene.addLayer(imageLayer); const threeJSLayer = new ThreeLayer({ @@ -84,10 +85,10 @@ export default class GlTFThreeJSDemo extends React.Component { // 根据 GeoJSON 数据放置模型 layer.getSource().data.dataArray.forEach(({ coordinates }) => { const gltfScene = gltf.scene; - - layer.adjustMeshToMap(gltfScene) - layer.setMeshScale(gltfScene, 10, 10, 10) - + + layer.adjustMeshToMap(gltfScene); + layer.setMeshScale(gltfScene, 10, 10, 10); + const animations = gltf.animations; if (animations && animations.length) { const mixer = new THREE.AnimationMixer(gltfScene); @@ -108,7 +109,6 @@ export default class GlTFThreeJSDemo extends React.Component { // 向场景中添加模型 threeScene.add(gltfScene); - // layer.setObjectLngLat(gltfScene, [120, 30], 0) // @ts-ignore // console.log(layer.mapService.lngLatToCoord([121.4, 31.258134]))