Skip to content

GLB或GLTF格式

示例

示例源码
vue
<template>
  <div style="height: 500px" class="vw-full vh-full">
    <div style="height: 400px">
      <mb-map
        :zoom="16"
        :center="mapCenter"
        :bearing="0"
        :pitch="45"
        @created="createdHandler"
      >
        <mb-tianditu-layer />
      </mb-map>
    </div>
  </div>
</template>
<script setup lang="ts">
import * as THREE from 'three'
// @ts-ignore
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'
import type { MapboxInstance } from '@mapbox-vue3/core'

const mapCenter = [116.3466, 39.8704]
let map: MapboxInstance
let mixers: THREE.AnimationMixer[] = []
let clock = new THREE.Clock()

const createdHandler = (mapbox: MapboxInstance) => {
  map = mapbox
  mixers = []
  clock = new THREE.Clock()
  loaderModels()
}
const loaderModels = () => {
  const loader = new GLTFLoader()
  loader.load(`${__RESOURCE_URL__}gltf/Flamingo/Flamingo.glb`, (gltf) => {
    const bird = gltf.scene

    bird.scale.multiplyScalar(150)
    bird.rotation.y = -1
    bird.rotation.x = Math.PI * 1.5

    const mixer = new THREE.AnimationMixer(gltf.scene.children[0])
    mixer.clipAction(gltf.animations[0]).setDuration(1).play()
    mixers.push(mixer)

    addThreeLayer(bird)
  })
}
const addThreeLayer = (bird) => {
  const threeLayer = new map.mapboxgl.supermap.ThreeLayer('threeLayer')
  threeLayer.on('initialized', render)
  let light: THREE.PointLight
  function render() {
    const renderer = threeLayer.getThreeRenderer(),
      scene = threeLayer.getScene(),
      camera = threeLayer.getCamera()

    light = new THREE.PointLight(0xffffff, 0.8)
    light.position.copy(camera.position)
    scene.add(light)
    scene.add(new THREE.AmbientLight(0xffffff))

    threeLayer.setPosition(bird, mapCenter)
    bird.translateY(500)

    scene.add(bird)
    ;(function animate() {
      bird.rotation.y += 0.01

      const delta = clock.getDelta()
      for (const mixer of mixers) {
        mixer.update(delta)
      }
      renderer.render(scene, camera)

      requestAnimationFrame(animate)
    })()
  }

  threeLayer.on('render', () => {
    light && light.position.copy(threeLayer.renderer.camera.position)
  })
  map.addLayer(threeLayer)
}
</script>