2020年6月

通过纹理的2维坐标点定位球形贴图对应所在位置

最近有一个需求,希望能在全景图的贴图上直接选择位置放置物体,最后反应在全景图的相应位置点.在这里记录一下开发代码:

全景球体创建

      let path = this.publicPath + 'texture/uv_grid_opengl.jpg'

      let texture = new THREE.TextureLoader().load(path)
      let material = new THREE.MeshBasicMaterial({
        map: texture,
        side: THREE.DoubleSide // 也可以是单面
      })

      let geometry = new THREE.SphereBufferGeometry(510, 40, 40) // 半径 ,宽高分割数.可以随意
      geometry.scale(-1, 1, 1) // 让贴图在内部贴,而不是外部.

      this.$mesh = new THREE.Mesh(geometry, material)

图片上选点

通过图片相对位置计算出在全景球体的相对坐标

参考代码:https://threejsfundamentals.org/threejs/lessons/threejs-align-html-elements-to-3d.html

      // x,y 的0点位置从左上角来算的,反应在图片上的长宽比值.
      // 因为geometry的x坐标返了,所以真也要相反处理
      let lat = (e.y - 0.5) * 180
      let lon = (1 - e.x) * 360

      const lonFudge = -Math.PI * 0.5 // Math.PI
      const latFudge = Math.PI
      // these helpers will make it easy to position the boxes
      // We can rotate the lon helper on its Y axis to the longitude
      const lonHelper = new THREE.Object3D()
      // We rotate the latHelper on its X axis to the latitude
      const latHelper = new THREE.Object3D()
      lonHelper.add(latHelper)
      // The position helper moves the object to the edge of the sphere
      const positionHelper = new THREE.Object3D()
      positionHelper.position.z = 500
      latHelper.add(positionHelper)

      // adjust the helpers to point to the latitude and longitude
      lonHelper.rotation.y = THREE.MathUtils.degToRad(lon) + lonFudge
      latHelper.rotation.x = THREE.MathUtils.degToRad(lat) + latFudge

      // get the position of the lat/lon
      positionHelper.updateWorldMatrix(true, false)
      const position = new THREE.Vector3()
      positionHelper.getWorldPosition(position)

      // 最终x,y点反应在球形位置上.
      let pos = [position.x, position.y, position.z]

全景图上效果