全景图和锚点编辑

今天来简单聊聊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全景图和锚点编辑内容请搜索Devmax以前的文章或继续浏览下面的相关文章希望大家以后多多支持Devmax!

threejs全景图和锚点编辑的实现方案的更多相关文章

  1. Three.js+React制作3D梦中海岛效果

    深居内陆的人们,大概每个人都有过大海之梦吧。本文使用React+Three.js技术栈,实现3D海洋和岛屿,感兴趣的小伙伴可以跟随小编一起学习一下

  2. javascript Three.js创建文字初体验

    这篇文章主要为大家介绍了Three.js创建文字初体验,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助

  3. Vue集成three.js并加载glb、gltf、FBX、json模型的场景分析

    这篇文章主要介绍了Vue集成three.js,并加载glb、gltf、FBX、json模型,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  4. Three.js+React实现带火焰效果的艾尔登法环

    《艾尔登法环》是最近比较火的一款游戏,观察可以发现它的 Logo 是由几个圆弧和线段构成。本文使用 React + Three.js 技术栈,实现具有火焰效果艾尔登法环 Logo,感兴趣的可以了解一下

  5. 利用Three.js制作一个新闻联播开头动画

    这篇文章主要为大家介绍了如何利用Three.js制作一个新闻联播开头动画,文中的实现步骤讲解详细,对我们学习有一定帮助,需要的可以参考一下

  6. Three.js实现脸书元宇宙3D动态Logo效果

    本文主要讲述通过 Three.js + Blender 技术栈,实现 Meta 公司炫酷的 3D 动态 Logo,内容包括基础模型圆环、环面扭结、管道及模型生成、模型加载、添加动画、添加点击事件、更换材质等

  7. Three.Js实现看房自由小项目

    目前随着元宇宙概念的爆火,THREE技术已经深入到了物联网、VR、游戏、数据可视化等多个平台,今天我们主要基于THREE实现一个三维的VR看房小项目,感兴趣的朋友跟随小编一起看看吧

  8. 使用three.js实现炫酷的酸性风格3D页面效果

    本文内容主要介绍,通过使用React+three.js技术栈,加载3D模型、添加3D文字、增加动画、点击交互等,配合样式设计,实现充满设计感的酸性风格页面

  9. 基于Three.js实现酷炫3D地图效果

    这篇文章主要为大家详细介绍了如何利用Three.js实现酷炫3D地图的效果,文中的示例代码讲解详细,具有一定的借鉴价值,感兴趣的小伙伴可以尝试一下

  10. three.js响应式设计实例详解

    响应式网站设计(Responsive Web design)是一种网络页面设计布局,是目前比较流行的一种网页设计,下面这篇文章主要给大家介绍了关于three.js响应式设计的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下

随机推荐

  1. js中‘!.’是什么意思

  2. Vue如何指定不编译的文件夹和favicon.ico

    这篇文章主要介绍了Vue如何指定不编译的文件夹和favicon.ico,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  3. 基于JavaScript编写一个图片转PDF转换器

    本文为大家介绍了一个简单的 JavaScript 项目,可以将图片转换为 PDF 文件。你可以从本地选择任何一张图片,只需点击一下即可将其转换为 PDF 文件,感兴趣的可以动手尝试一下

  4. jquery点赞功能实现代码 点个赞吧!

    点赞功能很多地方都会出现,如何实现爱心点赞功能,这篇文章主要为大家详细介绍了jquery点赞功能实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  5. AngularJs上传前预览图片的实例代码

    使用AngularJs进行开发,在项目中,经常会遇到上传图片后,需在一旁预览图片内容,怎么实现这样的功能呢?今天小编给大家分享AugularJs上传前预览图片的实现代码,需要的朋友参考下吧

  6. JavaScript面向对象编程入门教程

    这篇文章主要介绍了JavaScript面向对象编程的相关概念,例如类、对象、属性、方法等面向对象的术语,并以实例讲解各种术语的使用,非常好的一篇面向对象入门教程,其它语言也可以参考哦

  7. jQuery中的通配符选择器使用总结

    通配符在控制input标签时相当好用,这里简单进行了jQuery中的通配符选择器使用总结,需要的朋友可以参考下

  8. javascript 动态调整图片尺寸实现代码

    在自己的网站上更新文章时一个比较常见的问题是:文章插图太宽,使整个网页都变形了。如果对每个插图都先进行缩放再插入的话,太麻烦了。

  9. jquery ajaxfileupload异步上传插件

    这篇文章主要为大家详细介绍了jquery ajaxfileupload异步上传插件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. React学习之受控组件与数据共享实例分析

    这篇文章主要介绍了React学习之受控组件与数据共享,结合实例形式分析了React受控组件与组件间数据共享相关原理与使用技巧,需要的朋友可以参考下

返回
顶部