mapbox、three.js添加自定义3d模型

废话不多说,先看效果图
mapbox、three.js添加自定义3d模型_第1张图片

1、先初始化地图
我前面有完整的渲染地图的文章:https://blog.csdn.net/qq_41186500/article/details/103509936

    initMap() {
     
      mapboxgl.accessToken = 'pk.eyJ1IjoiMTgzODI0ZHl0IiwiYSI6ImNqbHExNDVjZzI0ZmUza2wxMDhocnlyem4ifQ.FZoJzmqTtli8hAvvAc1OPA'
      this.map = new mapboxgl.Map({
     
        style: 'mapbox://styles/mapbox/streets-v11',
        center: [118.78, 32.04],
        zoom: 10,
        container: 'mapbox'  // 盛放地图的容器id
      })
    },

2、添加自定义模型(正方体)

    initModel() {
     
      var map1 = this.map
      var modelOrigin = [118.78, 32.04]  // 添加模型的地理位置
      var modelAltitude = 0
      var modelRotate = [Math.PI / 2, 0, 0]
      var modelScale = 5.41843220338983e-8
        // transformation parameters to position, rotate and scale the 3D model onto the map
        var modelTransform = {
     
          translateX: mapboxgl.MercatorCoordinate.fromLngLat(modelOrigin , modelAltitude).x,
          translateY: mapboxgl.MercatorCoordinate.fromLngLat(modelOrigin , modelAltitude).y,
          translateZ: mapboxgl.MercatorCoordinate.fromLngLat(modelOrigin , modelAltitude).z,
          rotateX: modelRotate[0],
          rotateY: modelRotate[1],
          rotateZ: modelRotate[2],
          scale: modelScale
        }

        var THREE = window.THREE

        // configuration of the custom layer for a 3D model per the CustomLayerInterface
        var customLayer = {
     
          id: '3d-model',
          type: 'custom',
          renderingMode: '3d',
          onAdd: function(map, gl) {
     
            this.camera = new THREE.Camera()
            this.scene = new THREE.Scene()
            this.camera.position.set(3, 4, 10)
            this.renderer = new THREE.WebGLRenderer({
      canvas: map.getCanvas(), context: gl, antialias: true })
            var light = new THREE.PointLight(0xfca4c5)
            light.position.set(0, 250, 0)
            this.scene.add(light)

			// 自定义图片的正方体模型
            var texture = new THREE.TextureLoader().load(require('./10.png')) // 模型自定义图片
            var geometry = new THREE.BoxBufferGeometry(10, 10, 10) // 模型大小
            var material = new THREE.MeshBasicMaterial({
      map: texture })
            var mesh = new THREE.Mesh(geometry, material)
            mesh.position.set(0, 10, 10) // 模型在xyz轴位置
            this.scene.add(mesh)
            
			//  模型也可以换成自定义颜色,写法同自定义图片的方式差不多
			// var material = new THREE.MeshBasicMaterial({ color: '#256484' }) 
            // var geometry = new THREE.BoxBufferGeometry(10, 10, 10) // 模型大小
            // var mesh = new THREE.Mesh(geometry, material)
            // mesh.position.set(0, 10, 10) // 模型在xyz轴位置
            // this.scene.add(mesh)

            this.renderer.autoClear = false
          },
          render: function(gl, matrix) {
     
            var rotationX = new THREE.Matrix4().makeRotationAxis(
              new THREE.Vector3(1, 0, 0),
              modelTransform.rotateX
            )
            var rotationY = new THREE.Matrix4().makeRotationAxis(
              new THREE.Vector3(0, 1, 0),
              modelTransform.rotateY
            )
            var rotationZ = new THREE.Matrix4().makeRotationAxis(
              new THREE.Vector3(0, 0, 1),
              modelTransform.rotateZ
            )

            var m = new THREE.Matrix4().fromArray(matrix)
            var l = new THREE.Matrix4()
              .makeTranslation(
                modelTransform.translateX,
                modelTransform.translateY,
                modelTransform.translateZ
              )
              .scale(
                new THREE.Vector3(
                  modelTransform.scale,
                  -modelTransform.scale,
                  modelTransform.scale
                )
              )
              .multiply(rotationX)
              .multiply(rotationY)
              .multiply(rotationZ)

            this.camera.projectionMatrix = m.multiply(l)
            this.renderer.state.reset()
            this.renderer.render(this.scene, this.camera)
          }
        }
        console.log(customLayer)
        map1.on('style.load', function() {
     
          map1.addLayer(customLayer, 'waterway-label')
        })
      
    },

添加3d模型时有一个问题,我在添加模型的函数里将初始化的地图赋值给一个新的变量才能将模型渲染成功,直接用this.map.addLayer()的方法添加会报错,一定要将地图重新 style.load 加载才行

注:官网上的模型添加方式跟我修改后的方式稍有不同。由于官网的模型比较复杂,加载速度巨慢,我才改为引入图片做正方体这种方式,如果有大神能提供更好的方法,希望可以互相分享一ha呦~

附上官方添加3d模型的地址,给我看文档,一定要看文档!!!
https://docs.mapbox.com/mapbox-gl-js/example/add-3d-model/

题外话:由于加载较慢,一定要耐心等一下,模型不是没有,是太复杂了,加载巨慢。一般没报错的话就不要怀疑自己写的有问题哦,因为本人当初就是怀疑自己写的有问题。一直没有模型也没有报错,就怀疑是自己写的有问题,最后在面临放弃的时候,这个模型突然神奇的加出现了,此处仰天大笑三声。就在我写这篇文章的时候,我同步打开官网想在文章写完的时候贴上官网的例子,果然,一分钟过去了,一个小时过去了,一天过去了,一个月过去了,一年过去了,它突然就神奇的出现了。。。

mapbox、three.js添加自定义3d模型_第2张图片

你可能感兴趣的:(mapbox,vue,自定义3d模型)