threejs全景图和锚点编辑的实现方案

 更新时间:2022年04月14日 10:22:55   作者:Mool  
大家都知道可以利用Threejs中的立方体或者球体实现全景图功能,下面这篇文章主要给大家介绍了关于threejs全景图和锚点编辑的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下

全景图和锚点编辑

今天来简单聊聊threejs全景图和锚点编辑的方案。 全景图也就是所谓的天空盒子,所应用到的场景例如:场景模型的天空背景、夜晚的星空背景、VR看房等~

锚点编辑这篇重点讲一讲锚点编辑,也就是所谓场景编辑的方案。其中思想无限接近于Low Code,说到Low Code!我拖更了四篇文章,由于过年那段时间太忙了,实在是没时间更新!看到许多人都在等我完事,感到十分抱歉,后续一定会整理好更新!

全景图

其实全景图没什么内容。可以想象成一个非常大正方体的盒子,通过六个面的图片衔接而成。而我们相机则是存在于正方体内部,这样就能形成一个视觉误差,认为我们处于场景中。

全景图拆解

以下就是全景图正方体拆解图,六个面互相衔接,可以脑补下当将这个正方体组装后,我们所看到就是一个无缝衔接的一个场景,当然认真看还是可以看出正方体的边界处。

可以把骰子脑补成相机所在的位置,这样就很容易理解

既然有天空盒子,那多个场景的天空盒子肯定存在不同之处。在我们切换场景如何切换对应的天空盒子呢?很简单,我们只需封装一个切换函数如下

// 添加地面和天空盒
Viewer.prototype.changeSkyBox = function (skydir) {
  const that = this
  // 创建几何模型 BoxGeometry('x轴', '轴', 'z轴')
  const geometry = new THREE.BoxGeometry(999, 999, 999)
  // 创建纹理贴图  前后  上下  左右
  const texture0 = new THREE.TextureLoader().load((gAppPath + `/images/ysThree/sky/${skydir}/px.jpg`))
  const texture1 = new THREE.TextureLoader().load((gAppPath + `/images/ysThree/sky/${skydir}/nx.jpg`))
  const texture2 = new THREE.TextureLoader().load((gAppPath + `/images/ysThree/sky/${skydir}/py.jpg`))
  const texture3 = new THREE.TextureLoader().load((gAppPath + `/images/ysThree/sky/${skydir}/ny.jpg`))
  const texture4 = new THREE.TextureLoader().load((gAppPath + `/images/ysThree/sky/${skydir}/pz.jpg`))
  const texture5 = new THREE.TextureLoader().load((gAppPath + `/images/ysThree/sky/${skydir}/nz.jpg`))
  // 添加材质
  const material = [
    new THREE.MeshBasicMaterial({color: 0xffddff, map: texture0, side: THREE.DoubleSide}),
    new THREE.MeshBasicMaterial({color: 0xffddff, map: texture1, side: THREE.DoubleSide}),
    new THREE.MeshBasicMaterial({color: 0xffddff, map: texture2, side: THREE.DoubleSide}),
    new THREE.MeshBasicMaterial({color: 0xffddff, map: texture3, side: THREE.DoubleSide}),
    new THREE.MeshBasicMaterial({color: 0xffddff, map: texture4, side: THREE.DoubleSide}),
    new THREE.MeshBasicMaterial({color: 0xffddff, map: texture5, side: THREE.DoubleSide})
  ]
  // 创建网格对象
  const cube = new _3d.Mesh(geometry, material)
  cube.layers.enableAll()
  cube.name = 'skybox'
  that.skybox && this.scene.remove(that.skybox)
  that.skybox = cube
  that.AmbientGroup.add(cube)
}

场景编辑方案

不同场景的灯光位置以及图标点位可能不同,作为一个基础编辑平台,我们肯定要考虑如何将我们的场景变成可配置化,根据不同的需求做出不同的改变。之前的文章介绍过我们将模型通过JSON的形式去配置,那我们如何将场景中的点位以及灯光位置做出配置呢?

transformControls

变换控制器,这里它的作用主要是对锚点的平移、缩放、旋转操作

初始化控制器

//移动控制器
this.transformControls = new TransformControls(this.camera, this.renderer.domElement)
this.transformControls.setSize(0.5)
this.scene.add(this.transformControls) //添加入场景

添加可移动对象

我们可以在比如说灯光类中,添加一个transform_attach方法,在启用编辑后调用该方法。只有attach后才能够被拾取,进行平移、旋转、缩放的操作

transformControls.attach(...)
//对象类中
transform_attach(value){
  if (value) {
    this.transformControls.attach(this.dlight)
  }
  else {
    this.transformControls.detach(this.dlight)
  }
}

平移、缩放、旋转

gapp.history.execute 这里主要是业务逻辑,将编辑后的对象保存起来,主要用于回显

SetPositionCommand 这里主要的作用是记录下旧的位置信息与新的位置信息

抛开上面两个方法,其实只要添加进变换控制器就可以对物体就行操作了,下面我单独介绍为什么需要保存信息

Viewer.prototype.bindTransformEvent = function () {

  this.transformControls.addEventListener('mouseDown', () => { //鼠标拾取到
    var object = gapp.transformControls.object //获取拾取对象
    this.objectPositionOnDown = object.position.clone()//保存位置
    this.objectRotationOnDown = object.rotation.clone()//保存角度
    this.objectScaleOnDown = object.scale.clone()//保存缩放大小
    gapp.controls.enabled = false
  })
  this.transformControls.addEventListener('mouseUp', () => {//鼠标提起
    var object = gapp.transformControls.object//获取拾取对象
    if (object !== undefined) {
      switch (gapp.transformControls.getMode()) { //这里判断是要进行平移、缩放、旋转操作
        case 'translate':
          if (!this.objectPositionOnDown.equals(object.position)) {
            gapp.history.execute(new SetPositionCommand(this, object, object.position, this.objectPositionOnDown))
          }
          break
        case 'rotate':
          if (!this.objectRotationOnDown.equals(object.rotation)) {
            gapp.history.execute(new SetRotationCommand(this, object, object.rotation, this.objectRotationOnDown))
          }
          break
        case 'scale':
          if (!this.objectScaleOnDown.equals(object.scale)) {
            gapp.history.execute(new SetScaleCommand(this, object, object.scale, this.objectScaleOnDown))
          }
          break
      }
    }
    gapp.controls.enabled = true
  })
}

保存对象

其实这里和我Low Code的思想很像,就是我们最终要将所有配置好的物体信息保存成一个JSON的形式。以便于在任意其它项目中做回显。怎么回显呢? 假如说我们现在编辑好一个灯光的位置信息以及通过gui调整好的颜色、亮度等,我们可以将该灯光object对象通过toJSON转成JSON后存储于我们最终对象中,后续通过接口取回JSON通过转化重新add到场景中即可

//转化为threejs特有的json格式
 scene.toJSON() 
 (了解过json的同学可以发现,threejs为了缩小大小,将瓦片对象最大限度的拆分材质等,通过id关联并保存为json)
//解析json转为对象
Viewer.prototype.fromJSON = function (json, layeridx, isRayobj) {
  return new Promise((resolve, reject) => {
    // 解析 json 对象
    let loader = new THREE.ObjectLoader();
    let loadedMesh = loader.parse(json);
    let scene = this.mergeToMaterialsMap(loadedMesh, true)
    resolve(scene)
  })
}

结语

这篇文章主要介绍思想,相对来说这篇文章比较基础,当然后续可以根据自己的要求进行扩展

到此这篇关于threejs全景图和锚点编辑的文章就介绍到这了,更多相关threejs全景图和锚点编辑内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • js实现百度淘宝搜索功能

    js实现百度淘宝搜索功能

    这篇文章主要为大家详细介绍了js实现百度淘宝搜索功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-02-02
  • js 实现菜单上下显示附效果图

    js 实现菜单上下显示附效果图

    菜单上下显示的实现方法有很多,在本文将为大家介绍下使用js是如何实现的,需要的朋友不要错过
    2013-11-11
  • JavaScript实现文字与图片拖拽效果的方法

    JavaScript实现文字与图片拖拽效果的方法

    这篇文章主要介绍了JavaScript实现文字与图片拖拽效果的方法,涉及javascript操作文字与图片的技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-02-02
  • JavaScript作用域示例详解

    JavaScript作用域示例详解

    作用域是JavaScript最重要的概念之一,想要学好JavaScript就需要理解JavaScript作用域和作用域链的工作原理。今天这篇文章对JavaScript作用域示例详解的介绍,非常不错,感兴趣的朋友一起看下吧
    2016-07-07
  • Javascript中call的两种用法实例

    Javascript中call的两种用法实例

    这篇文章主要介绍了Javascript中call的两种用法实例,有需要的朋友可以参考一下
    2013-12-12
  • Bootstrap 设置datetimepicker在屏幕上面弹出设置方法

    Bootstrap 设置datetimepicker在屏幕上面弹出设置方法

    datetimepicker默认是在输入框下面弹出的,但是遇到输入框在屏幕下面时,日期选择框会有一部分在屏幕下面,显示不了,因此需要能够从上面弹出,下面小编给大家介绍下Bootstrap 设置datetimepicker在屏幕上面弹出的设置方法
    2017-03-03
  • 微信小程序详解如何实现付款功能

    微信小程序详解如何实现付款功能

    日常小程序里很多是需要付款的,那如何在小程序里实现付款呢?本篇就带着大家体验一下,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值
    2022-08-08
  • setTimeout和setInterval的区别你真的了解吗?

    setTimeout和setInterval的区别你真的了解吗?

    setTimeout和setInterval这两个函数, 大家肯定都不陌生, 但可能并不是每个用过这两个方法的同学, 都了解其内部的实质
    2011-03-03
  • 利用js来实现缩略语列表、文献来源链接和快捷键列表

    利用js来实现缩略语列表、文献来源链接和快捷键列表

    本文主要对利用js来实现缩略语列表、文献来源链接和快捷键列表的方法进行详细分析介绍。具有很好的参考价值,需要的朋友一起来看下吧
    2016-12-12
  • Bootstrap的Carousel配合dropload.js实现移动端滑动切换图片

    Bootstrap的Carousel配合dropload.js实现移动端滑动切换图片

    这篇文章主要介绍了bootstrap的Carousel配合dropload.js实现移动端滑动切换图片,实现方法非常简单,具有参考借鉴价值,需要的朋友可以参考下
    2017-03-03

最新评论