MapBox&ThreeJS加载FBX动态模型

1、Dom元素:

 2、import引入:

3、data(定义map,camera(镜头),scene(场景),stats(),mixer(),clock(时钟),customLayer(MapBox自定义图层)):

 4、methods(定位模型位置,创建自定义图层,加载模型,设置场景,设置镜头,设置光照,地图重新渲染将自定义层的模型加载到地图上,解析fbx模型骨骼动画,通过threejs的clock控件获得两帧之间的时间间隔,执行再次渲染函数render,渲染下一帧。):

methods: {
    initFBX() {
      var mapSecond = this.map
      // 用于确保模型在地图上正确地理参照的参数
      var modelOrigin = [148.9818395, -35.3985293]
      var modelAltitude = 0
      var modelRotate = [Math.PI / 2, 0, 0]

      var modelAsMercatorCoordinate = mapboxgl.MercatorCoordinate.fromLngLat(modelOrigin, modelAltitude)

      // 将三维模型定位、旋转和缩放到地图上的变换参数
      var modelTransform = {
        translateX: modelAsMercatorCoordinate.x,
        translateY: modelAsMercatorCoordinate.y,
        translateZ: modelAsMercatorCoordinate.z,
        rotateX: modelRotate[0],
        rotateY: modelRotate[1],
        rotateZ: modelRotate[2],
        /* Since our 3D model is in real world meters, a scale transform needs to be
         * applied since the CustomLayerInterface expects units in MercatorCoordinates.
         * 坐标转换,转为WebMercator
         */
        scale: modelAsMercatorCoordinate.meterInMercatorCoordinateUnits(),
      }

      var that = this
      // 为三维模型配置自定义图层
      this.customLayer = {
        id: '3d-model',
        type: 'custom',
        source: 'radar',
        renderingMode: '3d',

        onAdd: function (map, gl) {
          that.camera = new THREE.Camera()
          that.scene = new THREE.Scene()
          that.clock = new THREE.Clock()

          // 创建光源
          //环境光,无光照角度变化效果
          var ambient = new THREE.AmbientLight(0xffffff)
          that.scene.add(ambient)
          //平行光,比如太阳光
          // var directionalLight = new THREE.DirectionalLight(0xffffff)
          // directionalLight.position.set(0, -70, 100).normalize()
          // this.scene.add(directionalLight)

          // var directionalLight2 = new THREE.DirectionalLight(0xffffff)
          // directionalLight2.position.set(0, 70, 100).normalize()
          // this.scene.add(directionalLight2)

          // use the three.js GLTF loader to add the 3D model to the three.js scene
          var loader = new FBXLoader()
          loader.load(
            'http://219.146.77.222:18024/gis/Map/JumpingDown.fbx',
            function (fbx) {
              console.log(fbx.animations)
              that.scene.add(fbx)
              fbx.translateY(-80)
              that.mixer = new THREE.AnimationMixer(fbx)
              var AnimationAction = that.mixer.clipAction(fbx.animations[0])
              AnimationAction.play() //播放动画
            }.bind(that)
          )

          // use the Mapbox GL JS map canvas for three.js
          that.renderer = new THREE.WebGLRenderer({
            canvas: map.getCanvas(),
            context: gl,
            antialias: true,
          })
          that.renderer.autoClear = false
          that.clock = new THREE.Clock()
        },
        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)

          that.camera.projectionMatrix = m.multiply(l)

          that.renderer.state.reset()

          that.renderer.render(that.scene, that.camera)

          if (that.mixer !== null) {
            //clock.getDelta()方法获得两帧的时间间隔
            // 更新混合器相关的时间

            that.mixer.update(that.clock.getDelta())
          }
        },
      }
      //重新渲染地图
      mapSecond.on('style.load', () => {
        mapSecond.addLayer(this.customLayer, 'waterway-label')
        window.requestAnimationFrame(this.render)
      })
    },
    render(gl, matrix) {
      this.map.setFeatureState(
        {
          source: 'radar',
          sourceLayer: 'my-source-layer',
          id: '3d-model',
        },
        {
          hover: true,
        }
      )
      try {
      } catch {}
      window.requestAnimationFrame(this.render)
    },
  },

 5、mounted(加载地图,执行initFBX方法):

mounted() {
    mapboxgl.accessToken ='输入自己的token'
    this.map = new mapboxgl.Map({
      container: 'map', // container id
      style: 'mapbox://styles/mapbox/streets-v11', // stylesheet location
      center: [148.9819, -35.39847], // starting position [lng, lat]
      zoom: 18, // starting zoom
      pitch: 60,
      antialias: true, // create the gl context with MSAA antialiasing, so custom layers are antialiased
    })
    this.initFBX()
  }

6、style(定义地图样式):

猜你喜欢

转载自blog.csdn.net/weixin_47127256/article/details/129159688
今日推荐