Skip to content

OBJ

Example

Example Source Code
vue
<template>
  <div style="height: 500px" class="vw-full vh-full">
    <div style="height: 400px">
      <mb-map
        :zoom="15"
        :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 { OBJLoader } from 'three/addons/loaders/OBJLoader.js'
// @ts-ignore
import { MTLLoader } from 'three/addons/loaders/MTLLoader.js'
import type { MapboxInstance } from '@mapbox-vue3/core'

const mapCenter = [116.3466, 39.8704]
let map: MapboxInstance

const createdHandler = (mapbox: MapboxInstance) => {
  map = mapbox
  loaderModels()
}
const loaderModels = () => {
  const mtlLoader = new MTLLoader(new THREE.LoadingManager())

  mtlLoader.load(
    `${__RESOURCE_URL__}obj/windmill_2/windmill-fixed.mtl`,
    (materials) => {
      materials.preload()
      const objLoader = new OBJLoader(new THREE.LoadingManager())
      objLoader.setMaterials(materials)

      objLoader.load(
        `${__RESOURCE_URL__}obj/windmill_2/windmill.obj`,
        (obj) => {
          obj.traverse((child) => {
            if (child.isMesh) child.geometry.computeVertexNormals()
          })
          const meshes = obj
          meshes.rotation.x = -Math.PI / 2
          meshes.rotation.y = (1.4 * Math.PI) / 5
          meshes.scale.multiplyScalar(0.5)

          const otherObj = meshes.children[0].clone()
          otherObj.rotation.x = -Math.PI / 2
          otherObj.rotation.y = (1.4 * Math.PI) / 5
          otherObj.scale.multiplyScalar(0.5)

          addThreeLayer(meshes, otherObj)
        },
        null,
        null,
        null,
        false
      )
    }
  )
}
const addThreeLayer = (obj1, obj2) => {
  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(obj1, mapCenter)
    threeLayer.setPosition(
      obj2,
      mapCenter.map((c) => (c -= 0.0015))
    )
    obj1.translateY(300)

    scene.add(obj1)
    scene.add(obj2)
    renderer.render(scene, camera)
  }

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