vue中使用threejs和高德地图,加载3D模型。

1、准备工作 - 导入3D模型

首先在public中的static文件夹中导入编辑好的3D模型分别是mtl和obj格式的。如图:

2、安装依赖 - threejs和three-obj-mtl-loader

后者依赖前者,所有都要安装。

npm i -S three three-obj-mtl-loader

3、vue中引入高德地图

非常隐含的是,js API并没有离线版本。那么需要引入在线的高德地图。但是如何在vue组件中比较好的使用高德地图,网上查了一些方法,在这里综合一下:

异步创建一个script标签,把高德地图的地址(需要生成自己的key)放进去。如下例子

function createScript (url) {
    

    return new Promise((resolve, reject) => {
            
        let scriptElement = document.createElement('script')
        document.body.appendChild(scriptElement)
        scriptElement.src = url
        
    })

}


createScript('高德地图地址').then(resp => {

       // 地图的初始化
       ...

})

 

4、3D对象和地图之间的融合

首先需要在地图组件中引入上边安装过的依赖,如下:

import { OBJLoader, MTLLoader } from 'three-obj-mtl-loader' 

export default {
 ...

}

然后在地图开始地图初始化准备好地图实例:

// 初始化地图

initMap () {
    
    let map = new Amap.map({

        // 这里地图的配置

    })

}

初始化地图之后,开始解析3D模型了

mtlLoader.load(`static/elight.mtl`, function(materials) {
    materials.preload();

    // 初始化obj解析器
    let objLoader = new OBJLoader();

    // 开始引入3D对象文件进行解析
    objLoader.load(`static/elight.obj`, function(obj) {
        
        // 注意这个回调的参数obj就是我们传入的3D对象
        // 对象的children就是我们要的mesh对象 如下
        console.log('mesh', obj);
        let meshes = obj.children.length == 0 ? [] : obj.children;

        // 接下来很重要
        // 需要就是我们我们把这个mesh对象转变成高德地图可以认识的mesh对象
        // 
         meshes.forEach(meshItem => {
                let vecticesF3 = meshItem.geometry.attributes.position;
                let vecticesNormal3 = meshItem.geometry.attributes.normal;
                let vecticesUV2 = meshItem.geometry.attributes.uv;
                let vectexCount = vecticesF3.count;
                let material = meshItem.material[0] || meshItem.material;

                // 注意这里是高德地图的3d解析器   
                let mesh = new AMap.Object3D.MeshAcceptLights();
                let geometry = mesh.geometry;
                

                 // 以下就是改变3D模型的颜色
                for (var j = 0; j < vectexCount; j += 1) {
                  var s = j * 3;
                  geometry.vertices.push(vecticesF3.array[s], vecticesF3.array[s + 2], -vecticesF3.array[s + 1]);

                  if (vecticesNormal3) {
                    geometry.vertexNormals.push(vecticesNormal3.array[s], vecticesNormal3.array[s + 2], -
                      vecticesNormal3.array[s + 1]);
                  }
                  if (vecticesUV2) {
                    geometry.vertexUVs.push(vecticesUV2.array[j * 2], 1 - vecticesUV2.array[j * 2 + 1]);
                  }
                  // 真实颜色 0.81, 0.73, 0.45
                  geometry.vertexColors.push(...colorBg, 0.9) //0.87,0.93,0.72
                }


                // 以下是根据自己项目需求对这个3d对象调整颜色,旋转角度等属性的
                mesh.DEPTH_TEST = material.depthTest
                mesh.transparent = true; //opacity<1;
                mesh.scale(24, 18, 9) //11
                mesh.rotateZ(r)
                mesh.position(new AMap.LngLat(x, y));
                mesh.id = nid; //'light'+lightId;
                mesh.colorFlag = colorBg[0] == 0.81 ? '00' : '11';
                console.log('地图mesh', mesh);
                _this.meshes.push(mesh);

                // 最后需要把这个3D对象添加到地图的3D解析器中
                sobject3Dlayer.add(mesh);
              })
                

              // 然后需要把所有的3D对象添加到地图上  就可以看到地图上的3D模型了
              map.add(sobject3Dlayer);
    })
    
})

至此,差不多就是在地图中可以展示3D对象了的步骤了。

Logo

前往低代码交流专区

更多推荐