当前位置: 代码网 > it编程>编程语言>Javascript > THREE.JS使用TransformControls对模型拖拽的代码实例

THREE.JS使用TransformControls对模型拖拽的代码实例

2024年05月18日 Javascript 我要评论
一、原理: transformcontrols 是由 three.js 提供的一类控制器。 该类可提供一种类似于在数字内容创建工具(例如blender)中对模型进行交互的方式,来在3d空间中变

一、原理:

      transformcontrols 是由 three.js 提供的一类控制器。

      该类可提供一种类似于在数字内容创建工具(例如blender)中对模型进行交互的方式,来在3d空间中变换物体。 和其他控制器不同的是,变换控制器不倾向于对场景摄像机的变换进行改变。

       详见官网。

二、步骤:

  • 初始化场景
  • 引入transformcontrols控制器,并对其进行监听
  • 添加模型和连线
  • 根据控制器的改变对连线进行修改

三、代码:

<template>
  <div class="fa_container">
    <div class="container" ref="container"></div>
  </div>
</template>

<script>
import * as three from 'three'
import { orbitcontrols } from 'three/examples/jsm/controls/orbitcontrols'
import { transformcontrols } from 'three/examples/jsm/controls/transformcontrols.js'

const scene = new three.scene()
let renderer = new three.webglrenderer({
  antialias: true,
  alpha: true,
  logarithmicdepthbuffer: true
})
let camera, controls, transformcontrol

const pointer = new three.vector2()
const point = new three.vector3()
const raycaster = new three.raycaster()
let splinehelperobjects = []
const arc_segments = 200
let splines = []

export default {
  name: 'model',
  data () {
    return {
      positionlist: [
        [10, 0, 0],
        [-10, 0, 0]
      ]
    }
  },
  mounted () {
    this.init()
    this.addmarkmodel()
    this.render()
  },

  methods: {
    init () {
      this.dom = this.$refs['container']

      this.inithelper()
      this.initlight()
      this.initcamera()
      this.initrender()
      this.initcontrols()

      this.dom.addeventlistener('pointermove', e => {
        this.onpointermove(e)
      })
    },
    inithelper () {
      scene.background = new three.color(0xf0f0f0)

      // const axes = new three.axeshelper(50)
      // scene.add(axes)

      const planegeometry = new three.planegeometry(2000, 2000)
      planegeometry.rotatex(-math.pi / 2)
      const planematerial = new three.shadowmaterial({ color: 0x000000, opacity: 0.2 })
      const plane = new three.mesh(planegeometry, planematerial)
      plane.position.y = -200
      plane.receiveshadow = true
      scene.add(plane)

      const helper = new three.gridhelper(2000, 100)
      helper.position.y = -199
      helper.material.opacity = 0.25
      helper.material.transparent = true
      scene.add(helper)
    },
    initcamera () {
      camera = new three.perspectivecamera(
        45,
        this.dom.offsetwidth / this.dom.offsetheight,
        0.001,
        10000
      )
      camera.position.set(35, 35, 35)
    },
    initlight () {
      const directlight = new three.directionallight('#ffffff', 0.5)
      const directlight1 = new three.directionallight('#ffffff', 0.5)
      const directlight2 = new three.pointlight('#ffffff', 0.5)
      const ambientlight = new three.ambientlight('#ffffff', 0.3)

      directlight.castshadow = true
      directlight.position.set(15, 15, 15)
      directlight1.position.set(-15, -15, 15)
      ambientlight.position.set(0, 0, -5)
      directlight2.position.set(-15, 15, -15)
      directlight2.castshadow = true

      scene.add(directlight, directlight1, ambientlight, directlight2)
    },
    initrender () {
      renderer.setsize(1902, 935)
      renderer.outputencoding = three.srgbencoding
      this.dom.appendchild(renderer.domelement)
    },
    initcontrols () {
      controls = new orbitcontrols(camera, renderer.domelement)

      transformcontrol = new transformcontrols(camera, renderer.domelement)
      transformcontrol.addeventlistener('change', () => {
        console.log('模型拖动')
      })
      transformcontrol.addeventlistener('dragging-changed', function (event) {
        controls.enabled = !event.value
      })

      transformcontrol.addeventlistener('objectchange', param => {
        this.updatesplineoutline()
      })
      scene.add(transformcontrol)
    },

    // 鼠标移动
    onpointermove (event) {
      pointer.x = (event.clientx / window.innerwidth) * 2 - 1
      pointer.y = -(event.clienty / window.innerheight) * 2 + 1

      raycaster.setfromcamera(pointer, camera)

      const intersects = raycaster.intersectobjects(splinehelperobjects, false)

      if (intersects.length > 0) {
        const object = intersects[0].object

        if (object !== transformcontrol.object) {
          transformcontrol.attach(object)
          controls.enabled = false
        }
      }
    },
    // 更新连线
    updatesplineoutline () {
      for (let k = 0; k < splines.length; k++) {
        const spline = splines[k]
        const splinemesh = spline.mesh
        const position = splinemesh.geometry.attributes.position
        for (let i = 0; i < arc_segments; i++) {
          const t = i / (arc_segments - 1)
          spline.getpoint(t, point)
          position.setxyz(i, point.x, point.y, point.z)
        }
        position.needsupdate = true
      }
    },
    render () {
      requestanimationframe(this.render.bind(this))
      controls.update()
      renderer.render(scene, camera)
    },

    addmarkmodel () {
      for (let i = 0; i < this.positionlist.length; i++) {
        let position = []

        let obj1 = this.creatspot(this.positionlist[i], i)
        let obj2 = this.creathtml(i)

        settimeout(() => {
          position.push(obj1.position)
          position.push(obj2.position)
          this.creatline(position)
        }, 2000)
      }
    },
    creatspot (positionarr, index) {
      const sphergeometry = new three.spheregeometry(3, 32, 16)
      const sphermaterial = new three.meshlambertmaterial({ color: 'red' })
      const sphere = new three.mesh(sphergeometry, sphermaterial)
      sphere.position.set(positionarr[0], positionarr[1], positionarr[2])
      sphere.scale.set(0.2, 0.2, 0.2)
      splinehelperobjects.push(sphere)
      scene.add(sphere)
      return sphere
    },
    creathtml (index, spot) {
      const sphergeometry = new three.boxbuffergeometry(15, 15, 15)
      const sphermaterial = new three.meshphongmaterial({
        transparent: true,
        opacity: 1,
        color: 'green'
      })
      const sphere = new three.mesh(sphergeometry, sphermaterial)

      sphere.position.x = math.random() * 10
      sphere.position.y = math.random() * 20
      sphere.position.z = math.random() * 15
      sphere.scale.set(0.2, 0.2, 0.2)
      splinehelperobjects.push(sphere)
      scene.add(sphere)

      return sphere
    },
    creatline (position) {
      var curve = new three.catmullromcurve3(position)
      var points = curve.getpoints(arc_segments)
      var geometry = new three.buffergeometry().setfrompoints(points)
      var material = new three.linebasicmaterial({ color: 0xff0000 })

      curve.mesh = new three.linesegments(geometry, material)
      scene.add(curve.mesh)
      splines.push(curve)
    }
  }
}
</script>

<style>
.container {
  width: 1902px;
  height: 935px;
  overflow: hidden;
  background: black;
  display: inline-block;
}

</style>

四、最终效果:

拖拽前:

鼠标拾取模型:

模型拖动:

总结 

到此这篇关于three.js使用transformcontrols对模型拖拽的文章就介绍到这了,更多相关three.js对模型拖拽内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com