arcgis js API @4.26 3D场景渲染threejs模型

1 篇文章 0 订阅
1 篇文章 0 订阅

开局准备

为了方便测试本人用的是parcel打包工具创建的一个小项目,项目结构如图
在这里插入图片描述

在这里插入图片描述
mainjs引入的包

首先创建一个3D场景地图

arcgisJS文档查看点这里

const map = new Map({
  basemap: 'topo-vector',
});

const view = new SceneView({
  container: 'viewDiv', // 包含视图的容器
  map: map,
  // camera: {
  //   position: [104.06340647710485, 30.659828202233566, 1000],
  //   tilt: 45,
  // },
  center: [105, 29],
  zoom: 3,
});

重点创建一个外部渲染器

外部渲染器,需要必备的3个函数:setup render dispose
官方文档介绍
创建外部渲染器对象
在这里插入图片描述

完善setup函数

首先创建threejs的渲染器,并联系arcgis上下文gl

 this.renderer = new THREE.WebGLRenderer({
      context:context.gl,
      premultipliedAlpha:false
    })
    this.renderer.setPixelRatio(window.devicePixelRatio);
    this.renderer.setViewport(this.view.width, this.view.height);
 // 防止Three.js清除ArcGIS JS API提供的缓冲区。
    this.renderer.autoClearDepth = false; // 定义renderer是否清除深度缓存
    this.renderer.autoClearStencil = false; // 定义renderer是否清除模板缓存
    this.renderer.autoClearColor = false; // 定义renderer是否清除颜色缓存
	this.scene = new THREE.Scene(); // 场景
    this.camera = new THREE.PerspectiveCamera(); // 相机
    this.ambient = new THREE.AmbientLight(0xffffff, 0.5); // 环境光
    this.scene.add(this.ambient); // 把环境光添加到场景中
    this.sun = new THREE.DirectionalLight(0xffffff, 0.5); // 平行光(模拟太阳光)
    this.scene.add(this.sun); // 把太阳光添加到场景中

    // 添加坐标轴辅助工具
    const axesHelper = new THREE.AxesHelper(10000000);
    this.scene.add(axesHelper);

以上将ThreeJS必要的场景、相机、渲染器已经成功创建,现在我们来创建3D模型。创建一个立方体,这里设置的宽高与深度很大,方便观看效果。

const geometry = new THREE.BoxGeometry( 100000, 100000, 100000 );

现在是重点的坐标转换,目前存在的问题是这个模型的位置如何去对应arcgis场景的坐标位置。目前参考两种方法:

 let transform = new THREE.Matrix4(); // 变换矩阵
 let transformation = new Array(16);
 let vector3List = []; // 顶点数组
  // 转换顶点坐标
  points.forEach((point) => {
    // 将经纬度坐标转换为xy值\
    let pointXY = webMercatorUtils.lngLatToXY(经度, 维度);
    // 先转换高度为0的点
    transform.fromArray(
      externalRenderers.renderCoordinateTransformAt(
        this.view,
        [pointXY[0], pointXY[1], 0], // 坐标在地面上的点[x值, y值, 高度值]
        this.view.spatialReference,
        transformation
      )
    );
    vector3List.push(
      new THREE.Vector3(
        transform.elements[12],
        transform.elements[13],
        transform.elements[14]
      )
    );
   })

此生成的vector3List 就是物体在arcgis场景中相对于three坐标,对应的位置。
还有一种是arcgis api自带将外部空间坐标渲染到内部空间坐标的方法

 const entryPos = [105, 29, 550000]; // 输入位置 [经度, 纬度, 高程]
    const renderPos = new Array(3); // 渲染位置
    externalRenderers.toRenderCoordinates(
      view,
      entryPos,
      0,
      SpatialReference.WGS84,
      renderPos,
      0,
      1
      );
      console.log("转换后坐标",renderPos)

可以查看官方文档查阅,现在已经得到物体位置坐标,可以进行下一步将物体添加到场景中。

 const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
  this.obj = new THREE.Mesh( geometry, material );
  this.obj.position.set(...renderPos)
  this.scene.add( this.obj );

完善render函数

这里用来渲染物体的动态效果

// 获取ArcGIS场景中的大小
    const cam = context.camera;
    this.camera.position.set(cam.eye[0], cam.eye[1], cam.eye[2]);
    this.camera.up.set(cam.up[0], cam.up[1], cam.up[2]);
    this.camera.lookAt(
      new THREE.Vector3(cam.center[0], cam.center[1], cam.center[2])
    );
      // 投影矩阵可以直接复制
    this.camera.projectionMatrix.fromArray(cam.projectionMatrix);

    // this.obj.position.x += 1
    this.renderer.state.reset();
    context.bindRenderTarget()
    this.renderer.render(this.scene, this.camera);
    externalRenderers.requestRender(this.view);
    // cleanup
    context.resetWebGLState();

最后别忘了外部渲染器添加

externalRenderers.add(view, myRenderer);

运行代码已经能够看到立方体了

效果展示

在这里插入图片描述
参考

参考博主https://blog.csdn.net/qq_37155408/article/details/105295877?spm=1001.2014.3001.5506。他是渲染了一个外部模型。我这里渲染的是three自带的模型,对应初学者包括我自己,非常的友好。能够更加快速的理解渲染流程同时看到自己学习效果。

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值