Skip to content

OBJ格式

示例

示例源码
tsx
import React, { useCallback, useEffect, useRef, useState } from 'react'
import ReactDOM from 'react-dom'
import * as THREE from 'three'
import { OBJLoader } from 'OBJLoader'
import { MTLLoader } from 'MTLLoader'
import { MbMap, MbTiandituLayer } from '@mapbox-react/core'

const App = () => {
  const [mapCenter] = useState([116.3466, 39.8704])
  const [zoom, setZoom] = useState(15)
  const [pitch, setPitch] = useState(45)
  const mapInst = useRef<any>()

  let map: any
  const altitude = 0

  const mapCreated = (mapbox: any) => {
    map = mapbox
  }
  const add3DLayer = () => {
    loaderModels()
  }

  const loaderModels = () => {
    const mtlLoader = new MTLLoader(new THREE.LoadingManager())

    mtlLoader.load(
      `https://mapbox-web.github.io/mapbox-react/obj/windmill_2/windmill-fixed.mtl`,
      (materials) => {
        materials.preload()
        const objLoader = new OBJLoader(new THREE.LoadingManager())
        objLoader.setMaterials(materials)

        objLoader.load(
          `https://mapbox-web.github.io/mapbox-react/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)
  }

  return (
    <div className="map-wrapper">
      <MbMap
        ref={mapInst}
        center={mapCenter}
        zoom={zoom}
        pitch={pitch}
        onCreated={mapCreated}
      >
        <MbTiandituLayer types={['vec', 'cva']} onCreated={add3DLayer} />
      </MbMap>
    </div>
  )
}

ReactDOM.render(<App />, document.querySelector('#root'))